From 0a0d068ff46812c87c72c1ebe6e70373750c4b3f Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Fri, 18 Oct 2024 09:39:41 +0200 Subject: [PATCH 1/7] Split HOC/Py wrapper code printing. --- src/codegen/codegen_neuron_cpp_visitor.cpp | 75 ++++++++++++++-------- src/codegen/codegen_neuron_cpp_visitor.hpp | 17 +++++ 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.cpp b/src/codegen/codegen_neuron_cpp_visitor.cpp index dc8c39266..4834b1755 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.cpp +++ b/src/codegen/codegen_neuron_cpp_visitor.cpp @@ -282,19 +282,41 @@ void CodegenNeuronCppVisitor::print_function_procedure_helper(const ast::Block& } } - -void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_body( +void CodegenNeuronCppVisitor::print_hoc_py_wrapper_call_impl( const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type) { - if (info.point_process && wrapper_type == InterpreterWrapper::Python) { - return; - } + const auto block_name = function_or_procedure_block->get_node_name(); - if (wrapper_type == InterpreterWrapper::HOC) { - printer->fmt_push_block("{}", hoc_function_signature(block_name)); + + const auto get_func_call_str = [&]() { + const auto& params = function_or_procedure_block->get_parameters(); + const auto func_proc_name = block_name + "_" + info.mod_suffix; + auto func_call = fmt::format("{}({}", func_proc_name, internal_method_arguments()); + for (int i = 0; i < params.size(); ++i) { + func_call.append(fmt::format(", *getarg({})", i + 1)); + } + func_call.append(")"); + return func_call; + }; + if (function_or_procedure_block->is_function_block()) { + printer->add_indent(); + printer->fmt_text("_r = {};", get_func_call_str()); + printer->add_newline(); } else { - printer->fmt_push_block("{}", py_function_signature(block_name)); + printer->add_line("_r = 1.;"); + printer->fmt_line("{};", get_func_call_str()); + } + if (info.point_process || wrapper_type != InterpreterWrapper::HOC) { + printer->add_line("return(_r);"); + } else if (wrapper_type == InterpreterWrapper::HOC) { + printer->add_line("hoc_retpushx(_r);"); } +} + +void CodegenNeuronCppVisitor::print_hoc_py_wrapper_setup( + const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type) { + const auto block_name = function_or_procedure_block->get_node_name(); printer->add_multi_line(R"CODE( double _r{}; Datum* _ppvar; @@ -365,29 +387,26 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_body( table_update_function_name(block_name), internal_method_arguments()); } - const auto get_func_call_str = [&]() { - const auto& params = function_or_procedure_block->get_parameters(); - const auto func_proc_name = block_name + "_" + info.mod_suffix; - auto func_call = fmt::format("{}({}", func_proc_name, internal_method_arguments()); - for (int i = 0; i < params.size(); ++i) { - func_call.append(fmt::format(", *getarg({})", i + 1)); - } - func_call.append(")"); - return func_call; - }; - if (function_or_procedure_block->is_function_block()) { - printer->add_indent(); - printer->fmt_text("_r = {};", get_func_call_str()); - printer->add_newline(); - } else { - printer->add_line("_r = 1.;"); - printer->fmt_line("{};", get_func_call_str()); +} + +void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_body( + const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type) { + if (info.point_process && wrapper_type == InterpreterWrapper::Python) { + return; } - if (info.point_process || wrapper_type != InterpreterWrapper::HOC) { - printer->add_line("return(_r);"); + const auto block_name = function_or_procedure_block->get_node_name(); + if (info.point_process) { + printer->fmt_push_block("static double _hoc_{}(void* _vptr)", block_name); } else if (wrapper_type == InterpreterWrapper::HOC) { - printer->add_line("hoc_retpushx(_r);"); + printer->fmt_push_block("static void _hoc_{}(void)", block_name); + } else { + printer->fmt_push_block("static double _npy_{}(Prop* _prop)", block_name); } + + print_hoc_py_wrapper_setup(function_or_procedure_block, wrapper_type); + print_hoc_py_wrapper_call_impl(function_or_procedure_block, wrapper_type); + printer->pop_block(); } diff --git a/src/codegen/codegen_neuron_cpp_visitor.hpp b/src/codegen/codegen_neuron_cpp_visitor.hpp index 794c7dfbf..29457b3bc 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.hpp +++ b/src/codegen/codegen_neuron_cpp_visitor.hpp @@ -244,9 +244,26 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor { void print_function_procedure_helper(const ast::Block& node) override; + /** Print the wrapper for calling FUNCION/PROCEDURES from HOC/Py. + * + * Usually the function is made up of the following parts: + * * Print setup code `inst`, etc. + * * Print code to call the function and return. + */ void print_hoc_py_wrapper_function_body(const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type); + /** Print the setup code for HOC/Py wrapper. + */ + void print_hoc_py_wrapper_setup(const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type); + + + /** Print the code that calls the impl from the HOC/Py wrapper. + */ + void print_hoc_py_wrapper_call_impl(const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type); + void print_hoc_py_wrapper_function_definitions(); From fcfbbd1e9f47e3b73e53f862c23b1e6c9f765662 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Fri, 18 Oct 2024 09:42:52 +0200 Subject: [PATCH 2/7] Move printing return variable. --- src/codegen/codegen_neuron_cpp_visitor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.cpp b/src/codegen/codegen_neuron_cpp_visitor.cpp index 4834b1755..139a74fb3 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.cpp +++ b/src/codegen/codegen_neuron_cpp_visitor.cpp @@ -298,6 +298,9 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_call_impl( func_call.append(")"); return func_call; }; + + + printer->add_line("double _r = 0.0;"); if (function_or_procedure_block->is_function_block()) { printer->add_indent(); printer->fmt_text("_r = {};", get_func_call_str()); @@ -318,7 +321,6 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_setup( InterpreterWrapper wrapper_type) { const auto block_name = function_or_procedure_block->get_node_name(); printer->add_multi_line(R"CODE( - double _r{}; Datum* _ppvar; Datum* _thread; NrnThread* nt; From 22f889b697c37034d9cc94b7d1007643f768250e Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Fri, 18 Oct 2024 09:43:26 +0200 Subject: [PATCH 3/7] Rename HOC/Py wrapper function name. --- src/codegen/codegen_neuron_cpp_visitor.cpp | 9 ++++----- src/codegen/codegen_neuron_cpp_visitor.hpp | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.cpp b/src/codegen/codegen_neuron_cpp_visitor.cpp index 139a74fb3..f9864d930 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.cpp +++ b/src/codegen/codegen_neuron_cpp_visitor.cpp @@ -391,9 +391,8 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_setup( } } -void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_body( - const ast::Block* function_or_procedure_block, - InterpreterWrapper wrapper_type) { +void CodegenNeuronCppVisitor::print_hoc_py_wrapper(const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type) { if (info.point_process && wrapper_type == InterpreterWrapper::Python) { return; } @@ -416,8 +415,8 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_body( void CodegenNeuronCppVisitor::print_hoc_py_wrapper_function_definitions() { auto print_wrappers = [this](const auto& callables) { for (const auto& callable: callables) { - print_hoc_py_wrapper_function_body(callable, InterpreterWrapper::HOC); - print_hoc_py_wrapper_function_body(callable, InterpreterWrapper::Python); + print_hoc_py_wrapper(callable, InterpreterWrapper::HOC); + print_hoc_py_wrapper(callable, InterpreterWrapper::Python); } }; diff --git a/src/codegen/codegen_neuron_cpp_visitor.hpp b/src/codegen/codegen_neuron_cpp_visitor.hpp index 29457b3bc..d86679bd1 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.hpp +++ b/src/codegen/codegen_neuron_cpp_visitor.hpp @@ -250,8 +250,8 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor { * * Print setup code `inst`, etc. * * Print code to call the function and return. */ - void print_hoc_py_wrapper_function_body(const ast::Block* function_or_procedure_block, - InterpreterWrapper wrapper_type); + void print_hoc_py_wrapper(const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type); /** Print the setup code for HOC/Py wrapper. */ From 844bcbe40d4c32cccf4527ae4f8b5e0af3fbf56e Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Fri, 18 Oct 2024 09:58:41 +0200 Subject: [PATCH 4/7] Extract HOC/Py signature. --- src/codegen/codegen_neuron_cpp_visitor.cpp | 24 +++++++++++++--------- src/codegen/codegen_neuron_cpp_visitor.hpp | 6 ++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.cpp b/src/codegen/codegen_neuron_cpp_visitor.cpp index f9864d930..deee307e2 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.cpp +++ b/src/codegen/codegen_neuron_cpp_visitor.cpp @@ -285,7 +285,6 @@ void CodegenNeuronCppVisitor::print_function_procedure_helper(const ast::Block& void CodegenNeuronCppVisitor::print_hoc_py_wrapper_call_impl( const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type) { - const auto block_name = function_or_procedure_block->get_node_name(); const auto get_func_call_str = [&]() { @@ -299,7 +298,6 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_call_impl( return func_call; }; - printer->add_line("double _r = 0.0;"); if (function_or_procedure_block->is_function_block()) { printer->add_indent(); @@ -391,19 +389,25 @@ void CodegenNeuronCppVisitor::print_hoc_py_wrapper_setup( } } + +std::string CodegenNeuronCppVisitor::hoc_py_wrapper_signature( + const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type) { + const auto block_name = function_or_procedure_block->get_node_name(); + if (wrapper_type == InterpreterWrapper::HOC) { + return hoc_function_signature(block_name); + } else { + return py_function_signature(block_name); + } +} + void CodegenNeuronCppVisitor::print_hoc_py_wrapper(const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type) { if (info.point_process && wrapper_type == InterpreterWrapper::Python) { return; } - const auto block_name = function_or_procedure_block->get_node_name(); - if (info.point_process) { - printer->fmt_push_block("static double _hoc_{}(void* _vptr)", block_name); - } else if (wrapper_type == InterpreterWrapper::HOC) { - printer->fmt_push_block("static void _hoc_{}(void)", block_name); - } else { - printer->fmt_push_block("static double _npy_{}(Prop* _prop)", block_name); - } + + printer->push_block(hoc_py_wrapper_signature(function_or_procedure_block, wrapper_type)); print_hoc_py_wrapper_setup(function_or_procedure_block, wrapper_type); print_hoc_py_wrapper_call_impl(function_or_procedure_block, wrapper_type); diff --git a/src/codegen/codegen_neuron_cpp_visitor.hpp b/src/codegen/codegen_neuron_cpp_visitor.hpp index d86679bd1..453507a7c 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.hpp +++ b/src/codegen/codegen_neuron_cpp_visitor.hpp @@ -264,6 +264,12 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor { void print_hoc_py_wrapper_call_impl(const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type); + /** Return the wrapper signature. + * + * Everything without the { or ;. + */ + std::string hoc_py_wrapper_signature(const ast::Block* function_or_procedure_block, + InterpreterWrapper wrapper_type); void print_hoc_py_wrapper_function_definitions(); From 8569150c2172a07f6bc374875ac1d051092035e8 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Tue, 22 Oct 2024 08:18:32 +0000 Subject: [PATCH 5/7] Update src/codegen/codegen_neuron_cpp_visitor.hpp --- src/codegen/codegen_neuron_cpp_visitor.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.hpp b/src/codegen/codegen_neuron_cpp_visitor.hpp index 453507a7c..6ad316613 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.hpp +++ b/src/codegen/codegen_neuron_cpp_visitor.hpp @@ -266,7 +266,12 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor { /** Return the wrapper signature. * - * Everything without the { or ;. + * Everything without the { or ; as an example: + return_type function_name(, ) + + were ` is the list of arguments required by the + code to be passed along, while are the arguments in of + function as they appear in the MOD file. */ std::string hoc_py_wrapper_signature(const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type); From 74c7375c014668b1403fbdaaa6bfb76185b2226d Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Tue, 22 Oct 2024 10:23:06 +0200 Subject: [PATCH 6/7] Add documentation. --- src/codegen/codegen_neuron_cpp_visitor.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/codegen/codegen_neuron_cpp_visitor.hpp b/src/codegen/codegen_neuron_cpp_visitor.hpp index 6ad316613..33af424c5 100644 --- a/src/codegen/codegen_neuron_cpp_visitor.hpp +++ b/src/codegen/codegen_neuron_cpp_visitor.hpp @@ -266,12 +266,12 @@ class CodegenNeuronCppVisitor: public CodegenCppVisitor { /** Return the wrapper signature. * - * Everything without the { or ; as an example: - return_type function_name(, ) - - were ` is the list of arguments required by the - code to be passed along, while are the arguments in of - function as they appear in the MOD file. + * Everything without the `{` or `;`. Roughly, as an example: + * (, ) + * + * were ` is the list of arguments required by the + * codegen to be passed along, while are the arguments of + * of the function as they appear in the MOD file. */ std::string hoc_py_wrapper_signature(const ast::Block* function_or_procedure_block, InterpreterWrapper wrapper_type); From 46988fed55ea593540a53cfcc89b3bf7d9ecb528 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Tue, 22 Oct 2024 10:31:01 +0200 Subject: [PATCH 7/7] rerun ci