Skip to content

Commit

Permalink
Merge branch 'master' into jelic/macos_arm64_ci
Browse files Browse the repository at this point in the history
  • Loading branch information
JCGoran authored Apr 2, 2024
2 parents ff31c84 + 2edf9ac commit 20147a8
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 38 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/nmodl-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ jobs:
sanitizer: undefined
fail-fast: true
steps:
- name: Fix kernel mmap rnd bits
# Asan in llvm 14 provided in ubuntu 22.04 is incompatible with
# high-entropy ASLR in much newer kernels that GitHub runners are
# using leading to random crashes: https://reviews.llvm.org/D148280
run: sudo sysctl vm.mmap_rnd_bits=28
if: matrix.config.os == 'ubuntu-22.04'

- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ venv.bak/
# Generated files
test/usecases/*/x86_64
test/usecases/*/amd64
test/usecases/*/arm64
2 changes: 1 addition & 1 deletion ext/catch2
Submodule catch2 updated 276 files
2 changes: 1 addition & 1 deletion ext/cli11
Submodule cli11 updated 214 files
2 changes: 1 addition & 1 deletion ext/json
Submodule json updated 1152 files
2 changes: 1 addition & 1 deletion ext/pybind11
Submodule pybind11 updated 205 files
2 changes: 1 addition & 1 deletion ext/spdlog
Submodule spdlog updated 141 files
7 changes: 3 additions & 4 deletions src/codegen/codegen_neuron_cpp_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ std::string CodegenNeuronCppVisitor::float_variable_name(const SymbolType& symbo
std::string CodegenNeuronCppVisitor::int_variable_name(const IndexVariableInfo& symbol,
const std::string& name,
bool use_instance) const {
auto position = position_of_int_var(name);
// auto position = position_of_int_var(name);
if (symbol.is_index) {
if (use_instance) {
throw std::runtime_error("Not implemented. [wiejo]");
Expand Down Expand Up @@ -785,7 +785,8 @@ void CodegenNeuronCppVisitor::print_mechanism_global_var_structure(bool print_in
}


for (const auto& f: info.function_tables) {
// for (const auto& f: info.function_tables) {
if (!info.function_tables.empty()) {
throw std::runtime_error("Not implemented, global function tables.");
}

Expand Down Expand Up @@ -1033,7 +1034,6 @@ void CodegenNeuronCppVisitor::print_mechanism_register() {

for (int i = 0; i < codegen_int_variables_size; ++i) {
const auto& int_var = codegen_int_variables[i];

Check warning on line 1036 in src/codegen/codegen_neuron_cpp_visitor.cpp

View workflow job for this annotation

GitHub Actions / { "flag_warnings": "ON", "os": "ubuntu-22.04" }

unused variable ‘int_var’ [-Wunused-variable]

Check warning on line 1036 in src/codegen/codegen_neuron_cpp_visitor.cpp

View workflow job for this annotation

GitHub Actions / { "flag_warnings": "ON", "os": "ubuntu-22.04", "sanitizer": "undefined" }

unused variable 'int_var' [-Wunused-variable]
const auto& name = int_var.symbol->get_name();
if (i != info.semantics[i].index) {
throw std::runtime_error("Broken logic.");
}
Expand Down Expand Up @@ -1149,7 +1149,6 @@ void CodegenNeuronCppVisitor::print_make_instance() const {
}

void CodegenNeuronCppVisitor::print_node_data_structure(bool print_initializers) {
auto const value_initialize = print_initializers ? "{}" : "";
printer->add_newline(2);
printer->fmt_push_block("struct {} ", node_data_struct());

Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ int main(int argc, const char* argv[]) {
std::vector<fs::path> mod_files;

/// true if debug logger statements should be shown
std::string verbose("info");
std::string verbose("warning");

/// true if code is to be generated for NEURON
bool neuron_code(false);
Expand Down
75 changes: 61 additions & 14 deletions src/visitors/kinetic_block_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
#include "kinetic_block_visitor.hpp"

#include "ast/all.hpp"
#include "index_remover.hpp"
#include "symtab/symbol.hpp"
#include "utils/logger.hpp"
#include "utils/string_utils.hpp"
#include "visitor_utils.hpp"

#include <regex>


namespace nmodl {
namespace visitor {
Expand Down Expand Up @@ -141,24 +144,69 @@ void KineticBlockVisitor::visit_conserve(ast::Conserve& node) {
logger->debug("KineticBlockVisitor :: --> {}", to_nmodl(node));
}

void KineticBlockVisitor::set_compartment_factor(int var_index, const std::string& factor) {
if (compartment_factors[var_index] != "") {
throw std::runtime_error("Setting compartment volume twice.");
}

compartment_factors[var_index] = factor;
logger->debug("KineticBlockVisitor :: COMPARTMENT factor {} for state var {} (index {})",
factor,
state_var[var_index],
var_index);
}

void KineticBlockVisitor::compute_compartment_factor(ast::Compartment& node,
const ast::Name& name) {
const auto& var_name = name.get_node_name();
const auto it = state_var_index.find(var_name);
if (it != state_var_index.cend()) {
int var_index = it->second;
auto expr = node.get_expression();
std::string expression = to_nmodl(expr);

set_compartment_factor(var_index, expression);
} else {
logger->debug(
"KineticBlockVisitor :: COMPARTMENT specified volume for non-state variable {}",
var_name);
}
}

void KineticBlockVisitor::compute_indexed_compartment_factor(ast::Compartment& node,
const ast::Name& name) {
auto array_var_name = name.get_node_name();
auto index_name = node.get_name()->get_node_name();

auto pattern = fmt::format("^{}\\[([0-9]*)\\]$", array_var_name);
std::regex re(pattern);
std::smatch m;

for (size_t var_index = 0; var_index < state_var.size(); ++var_index) {
auto matches = std::regex_match(state_var[var_index], m, re);

if (matches) {
int index_value = std::stoi(m[1]);
auto volume_expr = node.get_expression();
auto expr = std::shared_ptr<ast::Expression>(node.get_expression()->clone());
IndexRemover(index_name, index_value).visit_expression(*expr);

std::string expression = to_nmodl(*expr);
set_compartment_factor(var_index, expression);
}
}
}

void KineticBlockVisitor::visit_compartment(ast::Compartment& node) {
// COMPARTMENT block has an expression, and a list of state vars it applies to.
// For each state var, the rhs of the differential eq should be divided by the expression.
// Here we store the expressions in the compartment_factors vector
auto expr = node.get_expression();
std::string expression = to_nmodl(expr);
logger->debug("KineticBlockVisitor :: COMPARTMENT expr: {}", expression);
logger->debug("KineticBlockVisitor :: COMPARTMENT expr: {}", to_nmodl(node.get_expression()));
for (const auto& name_ptr: node.get_names()) {
const auto& var_name = name_ptr->get_node_name();
const auto it = state_var_index.find(var_name);
if (it != state_var_index.cend()) {
int var_index = it->second;
compartment_factors[var_index] = expression;
logger->debug(
"KineticBlockVisitor :: COMPARTMENT factor {} for state var {} (index {})",
expression,
var_name,
var_index);
if (node.get_name() == nullptr) {
compute_compartment_factor(node, *name_ptr);
} else {
compute_indexed_compartment_factor(node, *name_ptr);
}
}
// add COMPARTMENT state to list of statements to remove
Expand Down Expand Up @@ -226,7 +274,6 @@ void KineticBlockVisitor::visit_reaction_statement(ast::ReactionStatement& node)
"KineticBlockVisitor :: LHS of \"<<\" reaction statement must be a single state "
"var, but instead found {}: ignoring this statement",
to_nmodl(lhs)));
return;
}
const auto& rhs = node.get_expression1();
std::string varname = to_nmodl(lhs);
Expand Down
4 changes: 4 additions & 0 deletions src/visitors/kinetic_block_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class KineticBlockVisitor: public AstVisitor {
/// update CONSERVE statement with reaction var term
void process_conserve_reac_var(const std::string& varname, int count = 1);

void set_compartment_factor(int var_index, const std::string& factor);
void compute_compartment_factor(ast::Compartment& node, const ast::Name& name);
void compute_indexed_compartment_factor(ast::Compartment& node, const ast::Name& name);

/// stochiometric matrices nu_L, nu_R
/// forwards/backwards fluxes k_f, k_b
/// (see kinetic_schemes.ipynb notebook for details)
Expand Down
1 change: 0 additions & 1 deletion src/visitors/semantic_analysis_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ void SemanticAnalysisVisitor::visit_name(const ast::Name& node) {
// There are only two contexts where a random_var is allowed. As the first arg of a random
// function or as an item in the RANDOM declaration.
// Only the former needs checking.
bool ok = true;
auto name = node.get_node_name();

// only check for variables exist in the symbol table (e.g. SUFFIX has type Name but it's not
Expand Down
13 changes: 7 additions & 6 deletions src/visitors/semantic_analysis_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@
* \brief \copybrief nmodl::visitor::SemanticAnalysisVisitor
*/

#include "ast/ast.hpp"
#include "visitors/ast_visitor.hpp"

namespace nmodl {
namespace visitor {

/**
* \addtogroup visitor_classes
* \{
*/

/**
* \class SemanticAnalysisVisitor
* \brief %Visitor to check some semantic rules on the ast
* \brief %Visitor to check some semantic rules on the AST
*
* Current checks:
*
Expand All @@ -34,11 +40,6 @@
* 8. Check that at most one derivative block is present.
* 9. Check that RANDOM variable is mentioned only as first arg in random function.
*/
#include "ast/ast.hpp"
#include "visitors/ast_visitor.hpp"

namespace nmodl {
namespace visitor {

class SemanticAnalysisVisitor: public ConstAstVisitor {
private:
Expand Down
20 changes: 20 additions & 0 deletions test/unit/visitor/kinetic_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,26 @@ SCENARIO("Convert KINETIC to DERIVATIVE using KineticBlock visitor", "[kinetic][
REQUIRE(result[0] == reindent_text(output_nmodl_text));
}
}
GIVEN("KINETIC block with -> reaction statement, indexed COMPARTMENT") {
std::string input_nmodl_text = R"(
STATE {
x[2]
}
KINETIC states {
COMPARTMENT i, vol[i] { x }
~ x[0] + x[1] -> (f(v))
})";
std::string output_nmodl_text = R"(
DERIVATIVE states {
x'[0] = ((-1*(f(v)*x[0]*x[1])))/(vol[0])
x'[1] = ((-1*(f(v)*x[0]*x[1])))/(vol[1])
})";
THEN("Convert to equivalent DERIVATIVE block") {
auto result = run_kinetic_block_visitor(input_nmodl_text);
CAPTURE(input_nmodl_text);
REQUIRE(result[0] == reindent_text(output_nmodl_text));
}
}
GIVEN("KINETIC block with one reaction statement, 1 state var, 1 non-state var, flux vars") {
// Here c is NOT a state variable
// see 9.9.2.1 of NEURON book
Expand Down
13 changes: 6 additions & 7 deletions test/usecases/generate_references.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ if [[ $# -eq 3 ]]
then
output_dir="$3"
else
script_dir="$(dirname "$(realpath "$0")")"
script_dir="$(cd "$(dirname "$0")"; pwd -P)"
output_dir="${script_dir}/references/$(basename "$2")"
fi

function sanitize() {
for f in "${1}"/*.cpp
do
if [[ "$(uname)" == 'Darwin' ]]
then
sed_cmd="sed -i''"
if [[ "$(uname)" == 'Darwin' ]]; then
sed_cmd=("sed" "-i" "")
else
sed_cmd="sed -i"
sed_cmd=("sed" "-i")
fi
${sed_cmd} "s/Created : .*$/Created : DATE/" "$f"
${sed_cmd} "s/NMODL Compiler : .*$/NMODL Compiler : VERSION/" "$f"
"${sed_cmd[@]}" "s/Created : .*$/Created : DATE/" "$f"
"${sed_cmd[@]}" "s/NMODL Compiler : .*$/NMODL Compiler : VERSION/" "$f"
done
}

Expand Down

0 comments on commit 20147a8

Please sign in to comment.