Skip to content

Commit

Permalink
ISPC codegen compatibility fixes (#105)
Browse files Browse the repository at this point in the history
This PR covers numerous fixes in the ISPC (and C) code generators working around many of real-world corner cases, which had been missed (or postponed) before:

* Fallback to C when VERBATIM nodes are found in AST
* Allow AstLookupVisitor::lookup to be called without a type
* Uses an additional instance of CodegenCVisistor that is constructed
  inside the ispc code generator as a fallback code generator.
* Removed the whole-file VERBATIM fallback in the main function.
* added missing constants
* filtered kernel routines, which contain verbatim blocks
* emit uncalled procedures and functions in C wrapper
* don't emit `printf` debug code
* rename PI into ISPC_PI to avoid name clashes with ispc constant
* emit functions that use tables in C
* Make sure that global data is shared between wrapper and ispc target
* Exclude Eigen node types from ISPC backend

This closes #83
  • Loading branch information
ohm314 authored Apr 1, 2019
1 parent 4f60b9b commit b8fc130
Show file tree
Hide file tree
Showing 12 changed files with 389 additions and 99 deletions.
21 changes: 16 additions & 5 deletions src/codegen/codegen_c_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1949,9 +1949,9 @@ std::string CodegenCVisitor::process_shadow_update_statement(ShadowUseStatement&
void CodegenCVisitor::print_nmodl_constant() {
printer->add_newline(2);
printer->add_line("/** constants used in nmodl */");
printer->add_line("static double FARADAY = 96485.3;");
printer->add_line("static double PI = 3.14159;");
printer->add_line("static double R = 8.3145;");
printer->add_line("static const double FARADAY = 96485.3;");
printer->add_line("static const double PI = 3.14159;");
printer->add_line("static const double R = 8.3145;");
}


Expand Down Expand Up @@ -2323,7 +2323,7 @@ void CodegenCVisitor::print_coreneuron_includes() {
* Note that static variables are already initialized to 0. We do the
* same for some variables to keep same code as neuron.
*/
void CodegenCVisitor::print_mechanism_global_var_structure() {
void CodegenCVisitor::print_mechanism_global_var_structure(bool wrapper) {
auto float_type = default_float_data_type();
printer->add_newline(2);
printer->add_line("/** all global variables */");
Expand Down Expand Up @@ -3796,6 +3796,7 @@ void CodegenCVisitor::visit_solution_expression(SolutionExpression* node) {
}
}


/****************************************************************************************/
/* Print nrn_state routine */
/****************************************************************************************/
Expand Down Expand Up @@ -4107,7 +4108,12 @@ void CodegenCVisitor::print_wrapper_routines() {
}


void CodegenCVisitor::visit_program(Program* node) {
void CodegenCVisitor::set_codegen_global_variables(std::vector<SymbolType>& global_vars) {
codegen_global_variables = global_vars;
}


void CodegenCVisitor::setup(Program* node) {
program_symtab = node->get_symbol_table();

CodegenHelperVisitor v;
Expand All @@ -4124,6 +4130,11 @@ void CodegenCVisitor::visit_program(Program* node) {

update_index_semantics();
rename_function_arguments();
}


void CodegenCVisitor::visit_program(Program* node) {
setup(node);
print_codegen_routines();
print_wrapper_routines();
}
Expand Down
109 changes: 66 additions & 43 deletions src/codegen/codegen_c_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ enum class BlockType {
State,

/// watch block
Watch
Watch,

/// net_receive block
NetReceive
};


Expand Down Expand Up @@ -561,7 +564,7 @@ class CodegenCVisitor: public AstVisitor {


/// nmodl constants
void print_nmodl_constant();
virtual void print_nmodl_constant();


/// top header printed in generated code
Expand Down Expand Up @@ -613,7 +616,7 @@ class CodegenCVisitor: public AstVisitor {


/// structure that wraps all global variables in the mod file
virtual void print_mechanism_global_var_structure();
virtual void print_mechanism_global_var_structure(bool wrapper = false);


/// structure that wraps all range and int variables required for mod file
Expand Down Expand Up @@ -764,26 +767,10 @@ class CodegenCVisitor: public AstVisitor {
void print_function_prototypes();


/// print check_function() for function/procedure using table
void print_table_check_function(ast::Block* node);


/// print replacement function for function/procedure using table
void print_table_replacement_function(ast::Block* node);


/// print check_table functions
void print_check_table_thread_function();


/// nmodl function definition
void print_function(ast::FunctionBlock* node);


/// nmodl procedure definition
void print_procedure(ast::ProcedureBlock* node);


/// print nmodl function or procedure (common code)
void print_function_or_procedure(ast::Block* node, std::string& name);

Expand Down Expand Up @@ -832,14 +819,6 @@ class CodegenCVisitor: public AstVisitor {
virtual void print_net_receive_loop_end();


/// kernel for buffering net_receive events
void print_net_receive_buffering(bool need_mech_inst = true);


/// net_receive kernel function definition
void print_net_receive_kernel();


/// net_receive function definition
void print_net_receive();

Expand Down Expand Up @@ -901,18 +880,6 @@ class CodegenCVisitor: public AstVisitor {
virtual void print_global_function_common_code(BlockType type);


/// nrn_init function definition
void print_nrn_init(bool skip_init_check = true);


/// nrn_state / state update function definition
void print_nrn_state();


/// nrn_cur / current update function definition
void print_nrn_cur();


/// mechanism registration function
void print_mechanism_register();

Expand All @@ -921,10 +888,6 @@ class CodegenCVisitor: public AstVisitor {
void print_watch_activate();


/// print watch activate function
void print_watch_check();


/// all includes
virtual void print_headers_include();

Expand Down Expand Up @@ -994,6 +957,66 @@ class CodegenCVisitor: public AstVisitor {
, layout(layout)
, float_type(float_type) {}


CodegenCVisitor(std::string mod_filename,
LayoutType layout,
std::string float_type,
std::shared_ptr<CodePrinter>& target_printer)
: target_printer(target_printer)
, printer(target_printer)
, mod_filename(mod_filename)
, layout(layout)
, float_type(float_type) {}


/// nrn_init function definition
void print_nrn_init(bool skip_init_check = true);


/// nrn_state / state update function definition
void print_nrn_state();


/// nrn_cur / current update function definition
void print_nrn_cur();


/// kernel for buffering net_receive events
void print_net_receive_buffering(bool need_mech_inst = true);


/// net_receive kernel function definition
void print_net_receive_kernel();


/// print watch activate function
void print_watch_check();


/// print check_function() for function/procedure using table
void print_table_check_function(ast::Block* node);


/// print replacement function for function/procedure using table
void print_table_replacement_function(ast::Block* node);


/// nmodl function definition
void print_function(ast::FunctionBlock* node);


/// nmodl procedure definition
virtual void print_procedure(ast::ProcedureBlock* node);


/** setup the Codgen, typically called from within visit_program but may be called from
* specialized targets to setup this Code generator as fallback.
*/
void setup(ast::Program* node);

void set_codegen_global_variables(std::vector<SymbolType>& global_vars);


virtual void visit_binary_expression(ast::BinaryExpression* node) override;
virtual void visit_binary_operator(ast::BinaryOperator* node) override;
virtual void visit_boolean(ast::Boolean* node) override;
Expand Down
10 changes: 10 additions & 0 deletions src/codegen/codegen_helper_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "visitors/rename_visitor.hpp"

#include <fmt/format.h>
#include <set>

using namespace fmt::literals;

Expand Down Expand Up @@ -121,6 +122,15 @@ void CodegenHelperVisitor::find_ion_variables() {
}
}
}

/// check if worte_conc(...) will be needed
for (const auto& ion: info.ions) {
for (const auto& var: ion.writes) {
if (!ion.is_ionic_current(var) && !ion.is_rev_potential(var)) {
info.require_wrote_conc = true;
}
}
}
}


Expand Down
5 changes: 4 additions & 1 deletion src/codegen/codegen_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ struct CodegenInfo {

/// true if EigenNewtonSolver is used in nrn_state block
bool nrn_state_has_eigen_solver_block() const;

/// if we need a call back to wrote_conc in neuron/coreneuron
bool require_wrote_conc = false;
};

} // namespace codegen
} // namespace nmodl
} // namespace nmodl
Loading

0 comments on commit b8fc130

Please sign in to comment.