diff --git a/.github/workflows/nestml-build.yml b/.github/workflows/nestml-build.yml index 8296ed89c..0832da265 100644 --- a/.github/workflows/nestml-build.yml +++ b/.github/workflows/nestml-build.yml @@ -47,6 +47,73 @@ jobs: run: | python3 extras/codeanalysis/check_copyright_headers.py && python3 -m pycodestyle $GITHUB_WORKSPACE -v --ignore=E241,E501,E714,E713,E714,E252,W503 --exclude=$GITHUB_WORKSPACE/doc,$GITHUB_WORKSPACE/.git,$GITHUB_WORKSPACE/NESTML.egg-info,$GITHUB_WORKSPACE/pynestml/generated,$GITHUB_WORKSPACE/extras,$GITHUB_WORKSPACE/build,$GITHUB_WORKSPACE/.github + build_and_test_py_standalone: + needs: [static_checks] + runs-on: ubuntu-latest + steps: + # Checkout the repository contents + - name: Checkout NESTML code + uses: actions/checkout@v3 + + # Setup Python version + - name: Setup Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + + # Install dependencies + - name: Install apt dependencies + run: | + sudo apt-get update + sudo apt-get install libgsl0-dev libncurses5-dev pkg-config + sudo apt-get install python3-all-dev python3-matplotlib python3-numpy python3-scipy ipython3 + + # Install Python dependencies + - name: Python dependencies + run: | + python -m pip install --upgrade pip pytest jupyterlab matplotlib pycodestyle scipy + python -m pip install -r requirements.txt + + # Install Java + - name: Install Java 11 + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: '11.0.x' + java-package: jre + + # Install Antlr4 + - name: Install Antlr4 + run: | + wget http://www.antlr.org/download/antlr-4.10-complete.jar + echo \#\!/bin/bash > antlr4 + echo java -cp \"`pwd`/antlr-4.10-complete.jar:$CLASSPATH\" org.antlr.v4.Tool \"\$@\" >> antlr4 + echo >> antlr4 + chmod +x antlr4 + echo PATH=$PATH:`pwd` >> $GITHUB_ENV + + # Install NESTML + - name: Install NESTML + run: | + export PYTHONPATH=${{ env.PYTHONPATH }}:${{ env.NEST_INSTALL }}/lib/python3.8/site-packages + #echo PYTHONPATH=`pwd` >> $GITHUB_ENV + echo "PYTHONPATH=$PYTHONPATH" >> $GITHUB_ENV + python setup.py install + + - name: Generate Lexer and Parser using Antlr4 + run: | + cd pynestml/grammars + ./generate_lexer_parser + + # Run integration tests + - name: Run integration tests + run: | + rc=0 + for fn in $GITHUB_WORKSPACE/tests/python_standalone_tests/*.py; do + pytest -s -o log_cli=true -o log_cli_level="DEBUG" ${fn} || rc=1 + done; + exit $rc + build_and_test: needs: [static_checks] runs-on: ubuntu-latest diff --git a/pynestml/codegeneration/printers/nest_variable_printer.py b/pynestml/codegeneration/printers/nest_variable_printer.py index ada23543c..4d2f40843 100644 --- a/pynestml/codegeneration/printers/nest_variable_printer.py +++ b/pynestml/codegeneration/printers/nest_variable_printer.py @@ -47,7 +47,6 @@ def __init__(self, expression_printer: ExpressionPrinter, with_origin: bool = Tr super().__init__(expression_printer) self.with_origin = with_origin self.with_vector_parameter = with_vector_parameter - self._state_symbols = [] def print_variable(self, variable: ASTVariable) -> str: """ @@ -159,8 +158,6 @@ def _print_buffer_value(self, variable: ASTVariable) -> str: return variable_symbol.get_symbol_name() + '_grid_sum_' def _print(self, variable: ASTVariable, symbol, with_origin: bool = True) -> str: - assert all([type(s) == str for s in self._state_symbols]) - variable_name = CppVariablePrinter._print_cpp_name(variable.get_complete_name()) if symbol.is_local(): diff --git a/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py b/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py index 0cc00e646..856bc1199 100644 --- a/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py +++ b/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py @@ -45,7 +45,7 @@ def print_variable(self, node: ASTVariable) -> str: symbol = node.get_scope().resolve_to_symbol(node.get_complete_name(), SymbolKind.VARIABLE) if symbol.is_state() and not symbol.is_inline_expression: - if node.get_complete_name() in self._state_symbols: + if "_is_numeric" in dir(node) and node._is_numeric: # ode_state[] here is---and must be---the state vector supplied by the integrator, not the state vector in the node, node.S_.ode_state[]. return "ode_state[node.S_.ode_state_variable_name_to_index[\"" + CppVariablePrinter._print_cpp_name(node.get_complete_name()) + "\"]]" diff --git a/pynestml/codegeneration/printers/python_variable_printer.py b/pynestml/codegeneration/printers/python_variable_printer.py index 554070a3a..63ccc9256 100644 --- a/pynestml/codegeneration/printers/python_variable_printer.py +++ b/pynestml/codegeneration/printers/python_variable_printer.py @@ -45,7 +45,6 @@ def __init__(self, expression_printer: ExpressionPrinter, with_origin: bool = Tr super().__init__(expression_printer) self.with_origin = with_origin self.with_vector_parameter = with_vector_parameter - self._state_symbols = [] @classmethod def _print_python_name(cls, variable_name: str) -> str: @@ -146,8 +145,6 @@ def _print_vector_parameter_name_reference(self, variable: ASTVariable) -> str: return self._expression_printer.print(vector_parameter) def _print(self, variable, symbol, with_origin: bool = True) -> str: - assert all([type(s) == str for s in self._state_symbols]) - variable_name = PythonVariablePrinter._print_python_name(variable.get_complete_name()) if symbol.is_local(): diff --git a/pynestml/codegeneration/python_code_generator_utils.py b/pynestml/codegeneration/python_code_generator_utils.py index 0e6792a00..41deeb944 100644 --- a/pynestml/codegeneration/python_code_generator_utils.py +++ b/pynestml/codegeneration/python_code_generator_utils.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from pynestml.meta_model.ast_variable import ASTVariable from pynestml.symbols.variable_symbol import VariableSymbol from pynestml.symbols.variable_symbol import BlockType @@ -26,14 +27,14 @@ class PythonCodeGeneratorUtils: @classmethod - def print_symbol_origin(cls, variable_symbol: VariableSymbol) -> str: + def print_symbol_origin(cls, variable_symbol: VariableSymbol, variable: ASTVariable) -> str: """ Returns a prefix corresponding to the origin of the variable symbol. :param variable_symbol: a single variable symbol. :return: the corresponding prefix """ if variable_symbol.block_type in [BlockType.STATE, BlockType.EQUATION]: - if numerical_state_symbols and variable_symbol.get_symbol_name() in numerical_state_symbols: + if "_is_numeric" in dir(variable) and variable._is_numeric: return 'self.S_.ode_state[self.S_.ode_state_variable_name_to_index["%s"]]' return 'self.S_.%s' diff --git a/pynestml/codegeneration/python_standalone_code_generator.py b/pynestml/codegeneration/python_standalone_code_generator.py index c18d70896..7d4a2c6b8 100644 --- a/pynestml/codegeneration/python_standalone_code_generator.py +++ b/pynestml/codegeneration/python_standalone_code_generator.py @@ -64,7 +64,8 @@ class PythonStandaloneCodeGenerator(NESTCodeGenerator): "neuron": ["@NEURON_NAME@.py.jinja2"] }, "module_templates": ["simulator.py.jinja2", "test_python_standalone_module.py.jinja2", "neuron.py.jinja2", "spike_generator.py.jinja2", "utils.py.jinja2"] - } + }, + "solver": "analytic" } def __init__(self, options: Optional[Mapping[str, Any]] = None): diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 index 4eb0e46c1..4dfa6aef8 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 @@ -786,7 +786,7 @@ void {{neuronName}}::handle(nest::DataLoggingRequest& e) void {{neuronName}}::handle(nest::SpikeEvent &e) { assert(e.get_delay_steps() > 0); - assert( e.get_rport() < static_cast< int >( B_.spike_inputs_.size() ) ); + assert( e.get_rport() < B_.spike_inputs_.size() ); double weight = e.get_weight(); size_t nestml_buffer_idx = 0; diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 index 668138497..8830bbaac 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2 @@ -241,7 +241,11 @@ public: /** * Used to validate that we can send {{ output_event.OutputEvent() }} to desired target:port. **/ +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t send_test_event(nest::Node& target, size_t receptor_type, nest::synindex, bool) override; +{%- else %} nest::port send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool) override; +{%- endif %} // ------------------------------------------------------------------------- // Functions handling incoming events. @@ -261,6 +265,7 @@ public: void handle(nest::DataLoggingRequest &) override;//! allow recording with multimeter +<<<<<<< HEAD {%- if use_gap_junctions %} void handle( nest::GapJunctionEvent& ) override; nest::port handles_test_event( nest::GapJunctionEvent&, nest::rport ) override; @@ -270,7 +275,27 @@ public: {%- endif %} +======= +{%- if has_spike_input %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t handles_test_event(nest::SpikeEvent&, size_t) override; +{%- else %} + nest::port handles_test_event(nest::SpikeEvent&, nest::port) override; +{%- endif %} +{%- endif %} +{%- if has_continuous_input %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t handles_test_event(nest::CurrentEvent&, size_t) override; +{%- else %} + nest::port handles_test_event(nest::CurrentEvent&, nest::port) override; +{%- endif %} +{%- endif %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t handles_test_event(nest::DataLoggingRequest&, size_t) override; +{%- else %} +>>>>>>> upstream/master nest::port handles_test_event(nest::DataLoggingRequest&, nest::port) override; +{%- endif %} // ------------------------------------------------------------------------- // Functions for getting/setting parameters and state values. @@ -409,13 +434,25 @@ private: * @note Excluded lower and upper bounds are defined as MIN_, MAX_. * Excluding port 0 avoids accidental connections. **/ +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + static const size_t MIN_SPIKE_RECEPTOR = 1; +{%- else %} static const nest::port MIN_SPIKE_RECEPTOR = 1; +{%- endif %} {%- set ns = namespace(count=1) %} +{%- else %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + static const size_t MIN_SPIKE_RECEPTOR = 0; {%- else %} static const nest::port MIN_SPIKE_RECEPTOR = 0; +{%- endif %} {%- set ns = namespace(count=0) %} {%- endif %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + static const size_t PORT_NOT_AVAILABLE = -1; +{%- else %} static const nest::port PORT_NOT_AVAILABLE = -1; +{%- endif %} enum SynapseTypes { @@ -817,7 +854,11 @@ private: }; /* neuron {{neuronName}} */ +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} +inline size_t {{neuronName}}::send_test_event(nest::Node& target, size_t receptor_type, nest::synindex, bool) +{%- else %} inline nest::port {{neuronName}}::send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool) +{%- endif %} { // You should usually not change the code in this function. // It confirms that the target of connection @c c accepts @c {{ output_event.OutputEvent() }} on @@ -828,7 +869,11 @@ inline nest::port {{neuronName}}::send_test_event(nest::Node& target, nest::rpor } {%- if has_spike_input %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} +inline size_t {{neuronName}}::handles_test_event(nest::SpikeEvent&, size_t receptor_type) +{%- else %} inline nest::port {{neuronName}}::handles_test_event(nest::SpikeEvent&, nest::port receptor_type) +{%- endif %} { {%- if (neuron.get_multiple_receptors())|length > 1 or neuron.is_multisynapse_spikes() %} assert( B_.spike_inputs_.size() == NUM_SPIKE_RECEPTORS ); @@ -852,7 +897,11 @@ inline nest::port {{neuronName}}::handles_test_event(nest::SpikeEvent&, nest::po {%- endif %} {%- if has_continuous_input %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} +inline size_t {{neuronName}}::handles_test_event(nest::CurrentEvent&, size_t receptor_type) +{%- else %} inline nest::port {{neuronName}}::handles_test_event(nest::CurrentEvent&, nest::port receptor_type) +{%- endif %} { // You should usually not change the code in this function. // It confirms to the connection management system that we are able @@ -866,7 +915,11 @@ inline nest::port {{neuronName}}::handles_test_event(nest::CurrentEvent&, nest:: } {%- endif %} +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} +inline size_t {{neuronName}}::handles_test_event(nest::DataLoggingRequest& dlr, size_t receptor_type) +{%- else %} inline nest::port {{neuronName}}::handles_test_event(nest::DataLoggingRequest& dlr, nest::port receptor_type) +{%- endif %} { // You should usually not change the code in this function. // It confirms to the connection management system that we are able diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 index f7347fb6b..481835855 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 @@ -165,14 +165,18 @@ public: long vtnode_id; if ( updateValue< long >( d, names::vt, vtnode_id ) ) { +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + const size_t tid = kernel().vp_manager.get_thread_id(); +{%- else %} const thread tid = kernel().vp_manager.get_thread_id(); +{%- endif %} {%- if nest_version.startswith("v2") %} Node* vt = kernel().node_manager.get_node( vtnode_id, tid ); {%- else %} Node* vt = kernel().node_manager.get_node_or_proxy( vtnode_id, tid ); {%- endif %} vt_ = dynamic_cast< volume_transmitter* >( vt ); - if ( vt_ == 0 ) + if ( vt_ == nullptr ) { throw BadProperty( "Neuromodulatory source must be volume transmitter" ); } @@ -192,11 +196,11 @@ public: {%- endfor %} {%- if vt_ports is defined and vt_ports|length > 0 %} - volume_transmitter* vt_; + volume_transmitter* vt_ = nullptr; inline long get_vt_node_id() const { - if ( vt_ != 0 ) + if ( vt_ != nullptr ) { {%- if nest_version.startswith("v2") %} return vt_->get_gid(); @@ -223,11 +227,18 @@ class {{synapseName}} : public Connection< targetidentifierT > {% endif %} {%- if vt_ports is defined and vt_ports|length > 0 %} public: +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + void trigger_update_weight( size_t t, + const std::vector< spikecounter >& vt_spikes, + double t_trig, + const {{synapseName}}CommonSynapseProperties& cp ); +{%- else %} void trigger_update_weight( thread t, const std::vector< spikecounter >& vt_spikes, double t_trig, const {{synapseName}}CommonSynapseProperties& cp ); {%- endif %} +{%- endif %} private: double t_lastspike_; {%- if vt_ports is defined and vt_ports|length > 0 %} @@ -236,7 +247,11 @@ private: // vt_spikes_idx_ refers to the vt spike that has just been processed after trigger_update_weight // a pseudo vt spike at t_trig is stored at index 0 and vt_spikes_idx_ = 0 +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t vt_spikes_idx_; +{%- else %} index vt_spikes_idx_; +{%- endif %} {%- endif %} /** @@ -270,7 +285,7 @@ private: {# N.B. numeric solver contains all state variables, including those that will be solved by analytic solver#} {%- if uses_numeric_solver %} // numeric solver state variables -{%- for variable_name in numeric_state_variables: %} +{%- for variable_name in numeric_state_variables %} {{variable_name}}, {%- endfor %} {%- endif %} @@ -446,8 +461,8 @@ public: {{synapseName}}( const {{synapseName}}& rhs ); {%- if vt_ports is defined and vt_ports|length > 0 %} -{%- set vt_port = vt_ports[0] %} - void process_{{vt_port}}_spikes_( const std::vector< spikecounter >& vt_spikes, +{%- set vt_port = vt_ports[0] %} + void process_{{ vt_port }}_spikes_( const std::vector< spikecounter >& vt_spikes, double t0, double t1, const {{synapseName}}CommonSynapseProperties& cp ); @@ -471,8 +486,13 @@ public: // Ensure proper overriding of overloaded virtual functions. // Return values from functions are ignored. using ConnTestDummyNodeBase::handles_test_event; +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( SpikeEvent&, size_t ) override +{%- else %} port handles_test_event( SpikeEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; @@ -480,56 +500,91 @@ public: return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( RateEvent&, size_t ) override +{%- else %} port handles_test_event( RateEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( DataLoggingRequest&, size_t ) override +{%- else %} port handles_test_event( DataLoggingRequest&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( CurrentEvent&, size_t ) override +{%- else %} port handles_test_event( CurrentEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( ConductanceEvent&, size_t ) override +{%- else %} port handles_test_event( ConductanceEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( DoubleDataEvent&, size_t ) override +{%- else %} port handles_test_event( DoubleDataEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( DSSpikeEvent&, size_t ) override +{%- else %} port handles_test_event( DSSpikeEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; {%- else %} return invalid_port; {%- endif %} } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + size_t + handles_test_event( DSCurrentEvent&, size_t ) override +{%- else %} port handles_test_event( DSCurrentEvent&, rport ) override +{%- endif %} { {%- if nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} return invalid_port_; @@ -558,11 +613,19 @@ public: assert(0); } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + void + check_connection( Node& s, + Node& t, + size_t receptor_type, + const CommonPropertiesType& cp ) +{%- else %} void check_connection( Node& s, Node& t, rport receptor_type, const CommonPropertiesType& cp ) +{%- endif %} { ConnTestDummyNode dummy_target; ConnectionBase::check_connection_( dummy_target, s, t, receptor_type ); @@ -578,7 +641,7 @@ public: {%- endif %} {%- if vt_ports is defined and vt_ports|length > 0 %} - if ( cp.vt_ == 0 ) + if ( cp.vt_ == nullptr ) { throw BadProperty( "No volume transmitter has been assigned to the dopamine synapse." ); } @@ -587,8 +650,13 @@ public: t.register_stdp_connection( t_lastspike_ - get_delay(), get_delay() ); } +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} + void + send( Event& e, const size_t tid, const {{synapseName}}CommonSynapseProperties& cp ) +{%- else %} void send( Event& e, const thread tid, const {{synapseName}}CommonSynapseProperties& cp ) +{%- endif %} { const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function @@ -1118,7 +1186,7 @@ template < typename targetidentifierT > {%- if vt_ports is defined and vt_ports|length > 0 %} t_last_update_ = rhs.t_last_update_; {%- endif %} - t_lastspike_ = rhs.t_lastspike_; + t_lastspike_ = rhs.t_lastspike_; // special treatment of NEST delay set_delay(rhs.get_delay()); @@ -1185,11 +1253,18 @@ inline void * Update to end of timestep ``t_trig``, while processing vt spikes and post spikes **/ template < typename targetidentifierT > +{%- if not (nest_version.startswith("v2") or nest_version.startswith("v3.0") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") or nest_version.startswith("v3.4")) %} inline void +{{synapseName}}< targetidentifierT >::trigger_update_weight( size_t t, + const std::vector< spikecounter >& vt_spikes, + const double t_trig, + const CommonPropertiesType& cp ) +{%- else %} {{synapseName}}< targetidentifierT >::trigger_update_weight( thread t, const std::vector< spikecounter >& vt_spikes, const double t_trig, const CommonPropertiesType& cp ) +{%- endif %} { // propagate all state variables in the synapse to time t_trig #ifdef DEBUG diff --git a/tests/python_standalone_tests/test_neuron_build_and_sim_analytic.py b/tests/python_standalone_tests/test_neuron_build_and_sim_analytic.py index 803c557ad..07a61874e 100644 --- a/tests/python_standalone_tests/test_neuron_build_and_sim_analytic.py +++ b/tests/python_standalone_tests/test_neuron_build_and_sim_analytic.py @@ -50,4 +50,4 @@ def test_python_standalone_neuron_build_and_sim_analytic(self): from nestmlmodule.test_python_standalone_module import TestSimulator neuron_log = TestSimulator().test_simulator() - np.testing.assert_allclose(neuron_log["V_abs"][-1], 11.192718053106296) + np.testing.assert_allclose(neuron_log["V_m"][-1], -58.80728194689356)