diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1192bf0..641400e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Python 3.x uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.12 # Install ubuntu dependencies - name: Ubuntu dependencies diff --git a/CMakeLists.txt b/CMakeLists.txt index e49b948..6a61d07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,35 +22,18 @@ cmake_minimum_required( VERSION 3.19 ) list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ) include( ProcessDependencies ) -# Name your module here. -set( SHORT_NAME my ) - # Build the complete module name: -set( MODULE_NAME ${SHORT_NAME}module ) - -# We require a module header containing the class description of the class -# extending the SLIModule -set( MODULE_HEADER src/${MODULE_NAME}.h ) +set( MODULE_NAME mymodule ) # Specify your module version -set( MODULE_VERSION_MAJOR 1 ) -set( MODULE_VERSION_MINOR 0 ) +set( MODULE_VERSION_MAJOR 0 ) +set( MODULE_VERSION_MINOR 1 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}" ) -# Set the `nest-config` executable to use during configuration. -set( with-nest OFF CACHE STRING "Specify the `nest-config` executable." ) - -# If it is not set, look for a `nest-config` in the PATH. -if ( NOT with-nest ) - # try find the program ourselves - find_program( NEST_CONFIG - NAMES nest-config - ) - if ( NEST_CONFIG STREQUAL "NEST_CONFIG-NOTFOUND" ) - message( FATAL_ERROR "Cannot find the program `nest-config`. Specify via -Dwith-nest=... ." ) - endif () +if ( with-nest ) + set( NEST_CONFIG ${with-nest} ) else () - set( NEST_CONFIG ${with-nest} ) + message( FATAL_ERROR "-Dwith-nest= is required" ) endif () # Use `nest-config` to get the compiler that was used for NEST. @@ -124,20 +107,6 @@ if ( NEST_INCLUDES ) endforeach () endif () -# Get, if NEST is build as a (mostly) static application. If yes, also only build -# static library. -execute_process( - COMMAND ${NEST_CONFIG} --static-libraries - RESULT_VARIABLE RES_VAR - OUTPUT_VARIABLE NEST_STATIC_LIB - OUTPUT_STRIP_TRAILING_WHITESPACE -) -if ( NEST_STATIC_LIB ) - set( BUILD_SHARED_LIBS OFF ) -else () - set( BUILD_SHARED_LIBS ON ) -endif () - # Get all linked libraries. execute_process( COMMAND ${NEST_CONFIG} --libs @@ -232,9 +201,6 @@ endforeach() add_subdirectory( src ) -# Install header file -install( FILES ${MODULE_HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${MODULE_NAME} ) - # Install help --- based on doc/CMakeLists.txt # Install only if Py >= 2.7.8 and NEST was installed with help if ( ( NOT CMAKE_CROSSCOMPILING ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8149bdf..607d069 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ # Add all your sources here and specify dependencies, e.g., link libraries set( MODULE_SOURCES - mymodule.h mymodule.cpp + mymodule.cpp pif_psc_alpha.h pif_psc_alpha.cpp drop_odd_spike_connection.h drop_odd_spike_connection.cpp step_pattern_builder.h step_pattern_builder.cpp @@ -37,34 +37,15 @@ else () message( "-- Skip build of recording backend >SoundClick<. sfml-audio is not installed." ) endif () -if ( BUILD_SHARED_LIBS ) - # When building shared libraries, also create a module for loading at runtime - # with the `Install` command. - add_library( ${MODULE_NAME}_module MODULE ${MODULE_SOURCES} ) - target_link_libraries(${MODULE_NAME}_module ${USER_LINK_LIBRARIES}) - set_target_properties( ${MODULE_NAME}_module - PROPERTIES - COMPILE_FLAGS "${NEST_CXXFLAGS} -DLTX_MODULE" - LINK_FLAGS "${NEST_LIBS}" - PREFIX "" - OUTPUT_NAME ${MODULE_NAME} ) - install( TARGETS ${MODULE_NAME}_module - DESTINATION ${CMAKE_INSTALL_LIBDIR}/nest - ) -endif () - -# Build dynamic/static library for standard linking from NEST. -add_library( ${MODULE_NAME}_lib ${MODULE_SOURCES} ) -if ( BUILD_SHARED_LIBS ) - # Dynamic libraries are initiated by a `global` variable of the `SLIModule`, - # which is included, when the flag `LINKED_MODULE` is set. - target_compile_definitions( ${MODULE_NAME}_lib PRIVATE -DLINKED_MODULE ) -endif () -set_target_properties( ${MODULE_NAME}_lib - PROPERTIES - COMPILE_FLAGS "${NEST_CXXFLAGS}" - LINK_FLAGS "${NEST_LIBS}" - OUTPUT_NAME ${MODULE_NAME} ) +add_library( ${MODULE_NAME}_module MODULE ${MODULE_SOURCES} ) +target_link_libraries(${MODULE_NAME}_module ${USER_LINK_LIBRARIES}) +set_target_properties( ${MODULE_NAME}_module + PROPERTIES + COMPILE_FLAGS "${NEST_CXXFLAGS} -DLTX_MODULE" + LINK_FLAGS "${NEST_LIBS}" + PREFIX "" + OUTPUT_NAME ${MODULE_NAME} ) +install( TARGETS ${MODULE_NAME}_module + DESTINATION ${CMAKE_INSTALL_LIBDIR}/nest + ) -# Install library -install( TARGETS ${MODULE_NAME}_lib DESTINATION ${CMAKE_INSTALL_LIBDIR}/nest ) diff --git a/src/mymodule.cpp b/src/mymodule.cpp index 7fcf3d9..a6128e1 100644 --- a/src/mymodule.cpp +++ b/src/mymodule.cpp @@ -20,11 +20,6 @@ * */ -#include "mymodule.h" - -// Generated includes: -#include "config.h" - // include headers with your own stuff #include "drop_odd_spike_connection.h" #include "pif_psc_alpha.h" @@ -34,95 +29,42 @@ #endif #include "recording_backend_socket.h" -// Includes from nestkernel: -#include "connection_manager_impl.h" -#include "connector_model_impl.h" -#include "dynamicloader.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" - -// Includes from sli: -#include "booldatum.h" -#include "integerdatum.h" -#include "sliexceptions.h" -#include "tokenarray.h" - -// -- Interface to dynamic module loader --------------------------------------- - -/* - * There are three scenarios, in which MyModule can be loaded by NEST: - * - * 1) When loading your module with `Install`, the dynamic module loader must - * be able to find your module. You make the module known to the loader by - * defining an instance of your module class in global scope. (LTX_MODULE is - * defined) This instance must have the name - * - * _LTX_mod - * - * The dynamicloader can then load modulename and search for symbol "mod" in it. - * - * 2) When you link the library dynamically with NEST during compilation, a new - * object has to be created. In the constructor the DynamicLoaderModule will - * register your module. (LINKED_MODULE is defined) - * - * 3) When you link the library statically with NEST during compilation, the - * registration will take place in the file `static_modules.h`, which is - * generated by cmake. - */ -#if defined( LTX_MODULE ) | defined( LINKED_MODULE ) -mynest::MyModule mymodule_LTX_mod; -#endif -// -- DynModule functions ------------------------------------------------------ +// Includes from NEST +#include "nest_extension_interface.h" -mynest::MyModule::MyModule() +namespace mynest { -#ifdef LINKED_MODULE - // register this module at the dynamic loader - // this is needed to allow for linking in this module at compile time - // all registered modules will be initialized by the main app's dynamic loader - nest::DynamicLoaderModule::registerLinkedModule( this ); -#endif -} + class MyModule : public nest::NESTExtensionInterface + { + public: + MyModule() {} + virtual ~MyModule() {} -mynest::MyModule::~MyModule() = default; - -const std::string -mynest::MyModule::name() const -{ - return std::string( "My NEST Module" ); // Return name of the module + void initialize() override; + }; } -//------------------------------------------------------------------------------------- +// Define module instance outside of namespace to avoid name-mangling problems +mynest::MyModule mymodule_LTX_module; -void -mynest::MyModule::init( SLIInterpreter* i ) +void mynest::MyModule::initialize() { /* Register a neuron or device model. - Give node type as template argument and the name as second argument. - */ - register_pif_psc_alpha( "pif_psc_alpha" ); + */ + mynest::register_pif_psc_alpha( "pif_psc_alpha" ); /* Register a synapse type. - Give synapse type as template argument and the name as second argument. - */ - register_drop_odd_spike_connection( "drop_odd_synapse" ); - + */ + mynest::register_drop_odd_spike_connection( "drop_odd_synapse" ); + // Register connection rule. - nest::kernel().connection_manager.register_conn_builder< StepPatternBuilder >( "step_pattern" ); + nest::kernel().connection_manager.register_conn_builder< mynest::StepPatternBuilder >( "step_pattern" ); #ifdef HAVE_SFML_AUDIO // Register recording backends. nest::kernel().io_manager.register_recording_backend< nest::RecordingBackendSoundClick >( "soundclick" ); #endif - nest::kernel().io_manager.register_recording_backend< nest::RecordingBackendSocket >( "socket" ); -} // MyModule::init() + nest::kernel().io_manager.register_recording_backend< mynest::RecordingBackendSocket >( "socket" ); +} + diff --git a/src/mymodule.h b/src/mymodule.h deleted file mode 100644 index ef3eb6e..0000000 --- a/src/mymodule.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * mymodule.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 MYMODULE_H -#define MYMODULE_H - -// Includes from sli: -#include "slifunction.h" -#include "slimodule.h" - -// Put your stuff into your own namespace. -namespace mynest -{ - -/** - * Class defining your model. - * @note For each model, you must define one such class, with a unique name. - */ -class MyModule : public SLIModule -{ -public: - // Interface functions ------------------------------------------ - - /** - * @note The constructor registers the module with the dynamic loader. - * Initialization proper is performed by the init() method. - */ - MyModule(); - - /** - * @note The destructor does not do much in modules. - */ - ~MyModule() override; - - /** - * Initialize module. - * @param SLIInterpreter* SLI interpreter - */ - void init( SLIInterpreter* ) override; - - /** - * Return the name of your module. - */ - const std::string name() const override; - -}; -} // namespace mynest - -#endif diff --git a/src/recording_backend_socket.cpp b/src/recording_backend_socket.cpp index bdadac4..117677f 100644 --- a/src/recording_backend_socket.cpp +++ b/src/recording_backend_socket.cpp @@ -32,43 +32,43 @@ #include "recording_backend_socket.h" -nest::RecordingBackendSocket::RecordingBackendSocket() +mynest::RecordingBackendSocket::RecordingBackendSocket() { } -nest::RecordingBackendSocket::~RecordingBackendSocket() throw() +mynest::RecordingBackendSocket::~RecordingBackendSocket() throw() { } void -nest::RecordingBackendSocket::initialize() +mynest::RecordingBackendSocket::initialize() { // nothing to do } void -nest::RecordingBackendSocket::finalize() +mynest::RecordingBackendSocket::finalize() { // nothing to do } void -nest::RecordingBackendSocket::enroll( const RecordingDevice& device, const DictionaryDatum& params ) +mynest::RecordingBackendSocket::enroll( const nest::RecordingDevice& device, const DictionaryDatum& params ) { - if ( device.get_type() != RecordingDevice::SPIKE_RECORDER ) + if ( device.get_type() != nest::RecordingDevice::SPIKE_RECORDER ) { - throw BadProperty( "Only spike recorders can record to recording backend 'socket'" ); + throw nest::BadProperty( "Only spike recorders can record to recording backend 'socket'" ); } } void -nest::RecordingBackendSocket::disenroll( const RecordingDevice& device ) +mynest::RecordingBackendSocket::disenroll( const nest::RecordingDevice& device ) { // nothing to do } void -nest::RecordingBackendSocket::set_value_names( const RecordingDevice&, +mynest::RecordingBackendSocket::set_value_names( const nest::RecordingDevice&, const std::vector< Name >&, const std::vector< Name >& ) { @@ -76,25 +76,25 @@ nest::RecordingBackendSocket::set_value_names( const RecordingDevice&, } void -nest::RecordingBackendSocket::pre_run_hook() +mynest::RecordingBackendSocket::pre_run_hook() { // nothing to do } void -nest::RecordingBackendSocket::post_run_hook() +mynest::RecordingBackendSocket::post_run_hook() { // nothing to do } void -nest::RecordingBackendSocket::post_step_hook() +mynest::RecordingBackendSocket::post_step_hook() { // nothing to do } void -nest::RecordingBackendSocket::prepare() +mynest::RecordingBackendSocket::prepare() { B_.addr_.sin_family = AF_INET; inet_aton( P_.ip_.c_str(), &B_.addr_.sin_addr ); @@ -104,18 +104,18 @@ nest::RecordingBackendSocket::prepare() } void -nest::RecordingBackendSocket::cleanup() +mynest::RecordingBackendSocket::cleanup() { close( B_.socket_ ); } void -nest::RecordingBackendSocket::write( const RecordingDevice& device, - const Event& event, +mynest::RecordingBackendSocket::write( const nest::RecordingDevice& device, + const nest::Event& event, const std::vector< double >& double_values, const std::vector< long >& long_values ) { - assert( device.get_type() == RecordingDevice::SPIKE_RECORDER ); + assert( device.get_type() == nest::RecordingDevice::SPIKE_RECORDER ); #pragma omp critical { @@ -129,21 +129,21 @@ nest::RecordingBackendSocket::write( const RecordingDevice& device, } } -nest::RecordingBackendSocket::Parameters_::Parameters_() +mynest::RecordingBackendSocket::Parameters_::Parameters_() : ip_( "127.0.0.1" ) , port_( 50000 ) { } void -nest::RecordingBackendSocket::Parameters_::get( DictionaryDatum& d ) const +mynest::RecordingBackendSocket::Parameters_::get( DictionaryDatum& d ) const { ( *d )[ "ip" ] = ip_; ( *d )[ "port" ] = port_; } void -nest::RecordingBackendSocket::Parameters_::set( const DictionaryDatum& d ) +mynest::RecordingBackendSocket::Parameters_::set( const DictionaryDatum& d ) { updateValue< std::string >( d, "ip", ip_ ); updateValue< long >( d, "port", port_ ); @@ -151,7 +151,7 @@ nest::RecordingBackendSocket::Parameters_::set( const DictionaryDatum& d ) // Set the status of the recording backend void -nest::RecordingBackendSocket::set_status( const DictionaryDatum& d ) +mynest::RecordingBackendSocket::set_status( const DictionaryDatum& d ) { Parameters_ ptmp = P_; // temporary copy in case of errors ptmp.set( d ); // throws if BadProperty @@ -162,25 +162,25 @@ nest::RecordingBackendSocket::set_status( const DictionaryDatum& d ) // Return the status of the recording backend void -nest::RecordingBackendSocket::get_status( DictionaryDatum& d ) const +mynest::RecordingBackendSocket::get_status( DictionaryDatum& d ) const { P_.get( d ); } void -nest::RecordingBackendSocket::check_device_status( const DictionaryDatum& ) const +mynest::RecordingBackendSocket::check_device_status( const DictionaryDatum& ) const { // nothing to do } void -nest::RecordingBackendSocket::get_device_defaults( DictionaryDatum& ) const +mynest::RecordingBackendSocket::get_device_defaults( DictionaryDatum& ) const { // nothing to do } void -nest::RecordingBackendSocket::get_device_status( const RecordingDevice&, DictionaryDatum& ) const +mynest::RecordingBackendSocket::get_device_status( const nest::RecordingDevice&, DictionaryDatum& ) const { // nothing to do } diff --git a/src/recording_backend_socket.h b/src/recording_backend_socket.h index f4a3299..61a3379 100644 --- a/src/recording_backend_socket.h +++ b/src/recording_backend_socket.h @@ -31,7 +31,7 @@ #include "recording_backend.h" -namespace nest +namespace mynest { /** @@ -54,7 +54,7 @@ namespace nest * all registered recording backends by IOManager::cleanup(). */ -class RecordingBackendSocket : public RecordingBackend +class RecordingBackendSocket : public nest::RecordingBackend { public: RecordingBackendSocket(); @@ -65,11 +65,11 @@ class RecordingBackendSocket : public RecordingBackend void finalize() override; - void enroll( const RecordingDevice& device, const DictionaryDatum& params ) override; + void enroll( const nest::RecordingDevice& device, const DictionaryDatum& params ) override; - void disenroll( const RecordingDevice& device ) override; + void disenroll( const nest::RecordingDevice& device ) override; - void set_value_names( const RecordingDevice& device, + void set_value_names( const nest::RecordingDevice& device, const std::vector< Name >& double_value_names, const std::vector< Name >& long_value_names ) override; @@ -83,7 +83,7 @@ class RecordingBackendSocket : public RecordingBackend void post_step_hook() override; - void write( const RecordingDevice&, const Event&, const std::vector< double >&, const std::vector< long >& ) override; + void write( const nest::RecordingDevice&, const nest::Event&, const std::vector< double >&, const std::vector< long >& ) override; void set_status( const DictionaryDatum& ) override; @@ -93,7 +93,7 @@ class RecordingBackendSocket : public RecordingBackend void get_device_defaults( DictionaryDatum& ) const override; - void get_device_status( const RecordingDevice&, DictionaryDatum& ) const override; + void get_device_status( const nest::RecordingDevice&, DictionaryDatum& ) const override; private: struct Parameters_