Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Fix Newton solver code generation#696

Merged
iomaganaris merged 27 commits into
masterfrom
magkanar/fix_newton
Aug 27, 2021
Merged

Fix Newton solver code generation#696
iomaganaris merged 27 commits into
masterfrom
magkanar/fix_newton

Conversation

@iomaganaris

@iomaganaris iomaganaris commented Jun 21, 2021

Copy link
Copy Markdown
Contributor
NEURON {
    RANGE tau
}
DERIVATIVE states {
    IF (tau == 1) {
    } ELSE {
        LOCAL tau
        tau = 1 + tau
    }
}

In this case tau should be DUState::U for example because as a GLOBAL variable we care about it's usage as a GLOBAL variable and not the LOCAL variable tau which is defined inside the IF-ELSE statement.

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #9336 (:white_check_mark:) have been uploaded here!

Status and direct links:

@iomaganaris iomaganaris force-pushed the magkanar/fix_newton branch from 42c604b to 6f7f7f7 Compare June 22, 2021 16:42
@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #9498 (:no_entry:) have been uploaded here!

Status and direct links:

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #9500 (:white_check_mark:) have been uploaded here!

Status and direct links:

@codecov-commenter

codecov-commenter commented Jun 29, 2021

Copy link
Copy Markdown

Codecov Report

Merging #696 (4599304) into master (d7b82bb) will increase coverage by 0.00%.
The diff coverage is 70.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #696   +/-   ##
=======================================
  Coverage   60.47%   60.47%           
=======================================
  Files         200      200           
  Lines       33283    33345   +62     
=======================================
+ Hits        20128    20167   +39     
- Misses      13155    13178   +23     
Impacted Files Coverage Δ
src/language/templates/visitors/symtab_visitor.hpp 42.85% <0.00%> (-17.15%) ⬇️
src/symtab/symbol_table.hpp 78.57% <ø> (ø)
src/codegen/codegen_c_visitor.cpp 63.43% <12.00%> (-0.46%) ⬇️
src/visitors/defuse_analyze_visitor.cpp 86.48% <100.00%> (+0.70%) ⬆️
src/visitors/defuse_analyze_visitor.hpp 93.33% <100.00%> (-6.67%) ⬇️
test/unit/visitor/defuse_analyze.cpp 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d7b82bb...4599304. Read the comment docs.

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #9993 (:white_check_mark:) have been uploaded here!

Status and direct links:

@iomaganaris iomaganaris marked this pull request as ready for review June 29, 2021 10:54
@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #11672 (:white_check_mark:) have been uploaded here!

Status and direct links:

@iomaganaris iomaganaris requested a review from pramodk July 23, 2021 14:30
Comment thread src/codegen/codegen_c_visitor.cpp Outdated
Comment on lines +1729 to +1737
// Create complete_block with both variable declarations (done in variable_block) and solver
// part (done in functor_block) to be able to run the SymtabVisitor and DefUseAnalyzeVisitor
// then and get the proper DUChains for the variables defined in the variable_block
ast::StatementBlock complete_block(functor_block);
// Typically variable_block has only one statement, a statement containing the declaration
// of the local variables
for (const auto& statement: variable_block.get_statements()) {
complete_block.insert_statement(complete_block.get_statements().begin(), statement);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a suggestion: with the similar code, you can also create ast::Program and insert nodes into it. That will solve the problem that we were discussing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit pain to do this in the end. Simply adding the StatementBlocks to the Program doesn't work because then SymtabVisitor is crashing due to redefinition of LOCAL variables which are handled as GLOBAL being in the top level of the Program. Instead of this I created a new constructor for the SymtabVisitor to get an empty ModelSymbolTable and be able to process any kind of node.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just clone the variable block? Or are you filtering something out? I do not understand exactly why you do this copy. Clearly is intentional

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's indeed optional. I am creating a new StatementBlock that just includes both the variable and functor_blocks

Comment thread src/visitors/symtab_visitor_helper.hpp Outdated
Comment on lines +167 to +169
if (modsymtab == nullptr) {
modsymtab = new symtab::ModelSymbolTable();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see the previous comment about avoiding this.

Comment thread src/visitors/defuse_analyze_visitor.cpp
@iomaganaris iomaganaris requested a review from cattabiani July 29, 2021 13:45
@cattabiani

Copy link
Copy Markdown
Contributor

may we add a small mod file that shows the problem in reduced_dentate? If I check the issue #691 I get a full repo and I do not know where is the problem

@iomaganaris

Copy link
Copy Markdown
Contributor Author

may we add a small mod file that shows the problem in reduced_dentate? If I check the issue #691 I get a full repo and I do not know where is the problem

This is the mod files I was testing this PR with https://github.com/pramodk/reduced_dentate/blob/master/mechanisms/Aradi_CadepK.mod

@cattabiani cattabiani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few questions and a suggestion for more unit tests. Overall very good job!

Comment thread src/codegen/codegen_c_visitor.cpp
Comment on lines +1729 to +1737
// Create complete_block with both variable declarations (done in variable_block) and solver
// part (done in functor_block) to be able to run the SymtabVisitor and DefUseAnalyzeVisitor
// then and get the proper DUChains for the variables defined in the variable_block
ast::StatementBlock complete_block(functor_block);
// Typically variable_block has only one statement, a statement containing the declaration
// of the local variables
for (const auto& statement: variable_block.get_statements()) {
complete_block.insert_statement(complete_block.get_statements().begin(), statement);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just clone the variable block? Or are you filtering something out? I do not understand exactly why you do this copy. Clearly is intentional

Comment thread src/symtab/symbol_table.hpp
Comment on lines +93 to +96
if ((variable_type == DUVariableType::Global &&
(child_state == DUState::U || child_state == DUState::D)) ||
(variable_type == DUVariableType::Local &&
(child_state == DUState::LU || child_state == DUState::LD))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a DUState::LU or DUState::LD without being a local variable? Otherwise this can be simplified

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The discrimination between DUVariableType::Global and DUVariableType::Local is needed so that we can discard any LD or LU of the variable we are analyzing if it's not a local_var on the Symbol Table. I couldn't think of any better way to do this while being as explanatory as possible. It's certainly a quite complex analysis

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a note: we discussed different alternatives to avoid introducing new DUVariableType (e.g. by using symbol table current_symtab directly. That avoids new type but we need some way to know the type).

We can go ahead with this implementation and revisit this if we see more use cases requiring further refactoring.

Comment on lines +140 to +141
if ((variable_type == DUVariableType::Global && child_state == DUState::U) ||
(variable_type == DUVariableType::Local && child_state == DUState::LU)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as before

Comment on lines +148 to +150
if ((variable_type == DUVariableType::Global && child_state == DUState::D) ||
(variable_type == DUVariableType::Local && child_state == DUState::LD) ||
child_state == DUState::CD) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as before

Comment thread src/visitors/defuse_analyze_visitor.hpp Outdated
Comment on lines +53 to +55
/// Variable type processed by DefUseAnalyzeVisitor
enum class DUVariableType { Local, Global };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary since it could be already specified with LU, LD

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT: in this case maybe we could simplify, rework update_defuse_chain to use this new enum. Dunno

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, this enum is used to define whether we are looking for the L, U or CD states of variable if it's a global variable in the SymTab or LU, LD or CD if it's a local variable in the SymTab. I should add a comment about this here

Comment thread test/unit/visitor/defuse_analyze.cpp
REQUIRE(chains[0].eval() == DUState::NONE);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few questions:

  • can you declare also GLOBAL inside the functor?
  • may we have also the following tests:
    • 2 local variables (used)
    • 2 local variables (1 unused)
    • 2 unused local variables
    • no local variables
    • a local variable in an IF ELSE block? Is it possible?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test that includes some of these cases that were not included before. I think it gives a good indication of how the DefUseAnalyzeVisitor works. Let me know if you want to add more cases 👍
GLOBAL variables are defined only in the NEURON block

@cattabiani

Copy link
Copy Markdown
Contributor

https://github.com/pramodk/reduced_dentate/blob/master/mechanisms/Aradi_CadepK.mod

there is not LOCAL inside a functor in this file. I do not connect the dots here. @iomaganaris ?

@iomaganaris

Copy link
Copy Markdown
Contributor Author

https://github.com/pramodk/reduced_dentate/blob/master/mechanisms/Aradi_CadepK.mod

there is not LOCAL inside a functor in this file. I do not connect the dots here. @iomaganaris ?

The original problem is that in with NMODL master the function operator is const:

void operator()(const Eigen::Matrix<double, 4, 1>& X, Eigen::Matrix<double, 4, 1>& F, Eigen::Matrix<double, 4, 4>& Jm) const {

while it writes variables which are members of the struct functor.
With this PR the qualifier const is not printed, so there is no compilation error with the generated file.

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #14671 (:no_entry:) have been uploaded here!

Status and direct links:

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #14670 (:no_entry:) have been uploaded here!

Status and direct links:

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #14674 (:no_entry:) have been uploaded here!

Status and direct links:

Comment thread src/codegen/codegen_c_visitor.cpp
Comment thread src/visitors/defuse_analyze_visitor.hpp
Comment thread src/visitors/defuse_analyze_visitor.cpp Outdated
Comment on lines +93 to +96
if ((variable_type == DUVariableType::Global &&
(child_state == DUState::U || child_state == DUState::D)) ||
(variable_type == DUVariableType::Local &&
(child_state == DUState::LU || child_state == DUState::LD))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a note: we discussed different alternatives to avoid introducing new DUVariableType (e.g. by using symbol table current_symtab directly. That avoids new type but we need some way to know the type).

We can go ahead with this implementation and revisit this if we see more use cases requiring further refactoring.

@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #14773 (:no_entry:) have been uploaded here!

Status and direct links:

@iomaganaris iomaganaris reopened this Aug 26, 2021
@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #14968 (:no_entry:) have been uploaded here!

Status and direct links:

@iomaganaris iomaganaris reopened this Aug 26, 2021
@bbpbuildbot

Copy link
Copy Markdown
Collaborator

Logfiles from GitLab pipeline #15023 (:white_check_mark:) have been uploaded here!

Status and direct links:

@iomaganaris

Copy link
Copy Markdown
Contributor Author

please retest

@pramodk pramodk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pramodk pramodk dismissed cattabiani’s stale review August 27, 2021 08:51

we have discussed some of the comments and certain parts are already addressed.

@iomaganaris iomaganaris merged commit 1321c7b into master Aug 27, 2021
@iomaganaris iomaganaris deleted the magkanar/fix_newton branch August 27, 2021 08:58
JCGoran pushed a commit to neuronsimulator/nrn that referenced this pull request Mar 12, 2025
* Fixes compilation issue when the operator() was declared as const while it changed some of values outside of its scope in the sympy solver

* Use DefUseAnalyzeVisitor to find out whether the operator() is Using or Defining any of the variables outside its scope

* Update DefUseAnalyzeVisitor to be able to process LOCAL variables as well, given precedence to GLOBAL/RANGE variables, when they have the same name

* Added related unit tests

* Fix codegen issue in CONSTRUCTOR and DESTRUCTOR blocks code when compiled for CoreNEURON

Fixes BlueBrain/nmodl#691
FIxes BlueBrain/nmodl#692 

NMODL Repo SHA: BlueBrain/nmodl@1321c7b
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error in code generation of reduced dentate benchmark (1)

6 participants