From 318f729d9e7dddfbb63bbd713cb63e8ccc71413d Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Tue, 20 Feb 2024 15:23:17 +0100 Subject: [PATCH] Update references for `1uc/sketch-golden-tests`. --- cnexp_array/coreneuron/leonhard.cpp | 299 +++++++++++++++++ cnexp_array/neuron/leonhard.cpp | 225 +++++++++++++ cnexp_scalar/coreneuron/leonhard.cpp | 283 ++++++++++++++++ cnexp_scalar/neuron/leonhard.cpp | 208 ++++++++++++ func_proc/coreneuron/func_proc.cpp | 285 ++++++++++++++++ func_proc/neuron/func_proc.cpp | 369 +++++++++++++++++++++ func_proc_pnt/coreneuron/func_proc_pnt.cpp | 283 ++++++++++++++++ func_proc_pnt/neuron/func_proc_pnt.cpp | 305 +++++++++++++++++ global_breakpoint/coreneuron/leonhard.cpp | 283 ++++++++++++++++ global_breakpoint/neuron/leonhard.cpp | 205 ++++++++++++ parameter/coreneuron/test_parameter.cpp | 257 ++++++++++++++ parameter/neuron/test_parameter.cpp | 214 ++++++++++++ point_process/coreneuron/test_pp.cpp | 254 ++++++++++++++ point_process/neuron/test_pp.cpp | 209 ++++++++++++ 14 files changed, 3679 insertions(+) create mode 100644 cnexp_array/coreneuron/leonhard.cpp create mode 100644 cnexp_array/neuron/leonhard.cpp create mode 100644 cnexp_scalar/coreneuron/leonhard.cpp create mode 100644 cnexp_scalar/neuron/leonhard.cpp create mode 100644 func_proc/coreneuron/func_proc.cpp create mode 100644 func_proc/neuron/func_proc.cpp create mode 100644 func_proc_pnt/coreneuron/func_proc_pnt.cpp create mode 100644 func_proc_pnt/neuron/func_proc_pnt.cpp create mode 100644 global_breakpoint/coreneuron/leonhard.cpp create mode 100644 global_breakpoint/neuron/leonhard.cpp create mode 100644 parameter/coreneuron/test_parameter.cpp create mode 100644 parameter/neuron/test_parameter.cpp create mode 100644 point_process/coreneuron/test_pp.cpp create mode 100644 point_process/neuron/test_pp.cpp diff --git a/cnexp_array/coreneuron/leonhard.cpp b/cnexp_array/coreneuron/leonhard.cpp new file mode 100644 index 0000000..c24bb7f --- /dev/null +++ b/cnexp_array/coreneuron/leonhard.cpp @@ -0,0 +1,299 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + "z_leonhard[3]", + 0, + "x_leonhard", + "s_leonhard[2]", + 0, + 0 + }; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + double s0{}; + int reset{}; + int mech_type{}; + int slist1[1]{3}; + int dlist1[1]{6}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* z{}; + double* x{}; + double* s{}; + double* Dx{}; + double* Ds{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 7; + } + + + static inline int int_variables_size() { + return 0; + } + + + static inline int get_mech_type() { + return leonhard_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new leonhard_Instance{}; + assert(inst->global == &leonhard_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(leonhard_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->z = ml->data+0*pnodecount; + inst->x = ml->data+3*pnodecount; + inst->s = ml->data+4*pnodecount; + inst->Dx = ml->data+6*pnodecount; + inst->Ds = ml->data+7*pnodecount; + inst->v_unused = ml->data+9*pnodecount; + inst->g_unused = ml->data+10*pnodecount; + } + + + + static void nrn_alloc_leonhard(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + /** initialize channel */ + void nrn_init_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->global->x0; + (inst->s+id*2)[0] = inst->global->s0; + (inst->s+id*2)[1] = inst->global->s0; + inst->x[id] = 42.0; + (inst->s+id*2)[static_cast(0)] = 0.1; + (inst->s+id*2)[static_cast(1)] = -1.0; + (inst->z+id*3)[static_cast(0)] = 0.7; + (inst->z+id*3)[static_cast(1)] = 0.8; + (inst->z+id*3)[static_cast(2)] = 0.9; + } + } + } + + + /** update state */ + void nrn_state_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->x[id] + (1.0 - exp(nt->_dt * ((((inst->s+id*2)[static_cast(0)] + (inst->s+id*2)[static_cast(1)]) * ((inst->z+id*3)[static_cast(0)] * (inst->z+id*3)[static_cast(1)] * (inst->z+id*3)[static_cast(2)])) * (1.0)))) * ( -(0.0) / (((((inst->s+id*2)[static_cast(0)] + (inst->s+id*2)[static_cast(1)])) * (((((inst->z+id*3)[static_cast(0)]) * ((inst->z+id*3)[static_cast(1)])) * ((inst->z+id*3)[static_cast(2)])))) * (1.0)) - inst->x[id]); + } + } + + + /** register channel with the simulator */ + void _leonhard_reg() { + + int mech_type = nrn_get_mechtype("leonhard"); + leonhard_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nullptr, nrn_state_leonhard, nrn_init_leonhard, nrn_private_constructor_leonhard, nrn_private_destructor_leonhard, first_pointer_var_index(), 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/cnexp_array/neuron/leonhard.cpp b/cnexp_array/neuron/leonhard.cpp new file mode 100644 index 0000000..5a0c9be --- /dev/null +++ b/cnexp_array/neuron/leonhard.cpp @@ -0,0 +1,225 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 0; +static constexpr auto number_of_floating_point_variables = 7; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +Prop* hoc_getdata_range(int type); + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + "z_leonhard[3]", + 0, + "x_leonhard", + "s_leonhard[2]", + 0, + 0 + }; + + + /* NEURON global variables */ + static neuron::container::field_index _slist1[1], _dlist1[1]; + static int mech_type; + static Prop* _extcall_prop; + /* _prop_id kind of shadows _extcall_prop to allow validity checking. */ + static _nrn_non_owning_id_without_container _prop_id{}; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + double s0{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* z{}; + double* x{}; + double* s{}; + double* Dx{}; + double* Ds{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + static leonhard_Instance make_instance_leonhard(_nrn_mechanism_cache_range& _ml) { + return leonhard_Instance { + _ml.template data_array_ptr<0, 3>(), + _ml.template fpfield_ptr<1>(), + _ml.template data_array_ptr<2, 2>(), + _ml.template fpfield_ptr<3>(), + _ml.template data_array_ptr<4, 2>(), + _ml.template fpfield_ptr<5>(), + _ml.template fpfield_ptr<6>() + }; + } + + + static void nrn_alloc_leonhard(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 7); + /*initialize range parameters*/ + } + + + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + _extcall_prop = _prop; + _prop_id = _nrn_get_prop_id(_prop); + } + static void _hoc_setdata() { + Prop *_prop = hoc_getdata_range(mech_type); + _setdata(_prop); + hoc_retpushx(1.); + } + /* Mechanism procedures and functions */ + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {"setdata_leonhard", _hoc_setdata}, + {0, 0} + }; + static NPyDirectMechFunc npy_direct_func_proc[] = { + }; + + + void nrn_init_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = 42.0; + (inst.s+id*2)[static_cast(0)] = 0.1; + (inst.s+id*2)[static_cast(1)] = -1.0; + (inst.z+id*3)[static_cast(0)] = 0.7; + (inst.z+id*3)[static_cast(1)] = 0.8; + (inst.z+id*3)[static_cast(2)] = 0.9; + } + } + + + void nrn_state_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = inst.x[id] + (1.0 - exp(_nt->_dt * ((((inst.s+id*2)[static_cast(0)] + (inst.s+id*2)[static_cast(1)]) * ((inst.z+id*3)[static_cast(0)] * (inst.z+id*3)[static_cast(1)] * (inst.z+id*3)[static_cast(2)])) * (1.0)))) * ( -(0.0) / (((((inst.s+id*2)[static_cast(0)] + (inst.s+id*2)[static_cast(1)])) * (((((inst.z+id*3)[static_cast(0)]) * ((inst.z+id*3)[static_cast(1)])) * ((inst.z+id*3)[static_cast(2)])))) * (1.0)) - inst.x[id]); + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + /* x */ + _slist1[0] = {1, 0}; + /* Dx */ + _dlist1[0] = {3, 0}; + } + + + /** register channel with the simulator */ + extern "C" void _leonhard_reg() { + _initlists(); + + + + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nrn_jacob_leonhard, nrn_state_leonhard, nrn_init_leonhard, hoc_nrnpointerindex, 1); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"z", 3} /* 0 */, + _nrn_mechanism_field{"x"} /* 1 */, + _nrn_mechanism_field{"s", 2} /* 2 */, + _nrn_mechanism_field{"Dx"} /* 3 */, + _nrn_mechanism_field{"Ds", 2} /* 4 */, + _nrn_mechanism_field{"v_unused"} /* 5 */, + _nrn_mechanism_field{"g_unused"} /* 6 */ + ); + + hoc_register_prop_size(mech_type, 7, 0); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + hoc_register_npy_direct(mech_type, npy_direct_func_proc); + } +} diff --git a/cnexp_scalar/coreneuron/leonhard.cpp b/cnexp_scalar/coreneuron/leonhard.cpp new file mode 100644 index 0000000..1462a74 --- /dev/null +++ b/cnexp_scalar/coreneuron/leonhard.cpp @@ -0,0 +1,283 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + 0, + "x_leonhard", + 0, + 0 + }; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + int reset{}; + int mech_type{}; + int slist1[1]{0}; + int dlist1[1]{1}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* x{}; + double* Dx{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 4; + } + + + static inline int int_variables_size() { + return 0; + } + + + static inline int get_mech_type() { + return leonhard_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new leonhard_Instance{}; + assert(inst->global == &leonhard_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(leonhard_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->x = ml->data+0*pnodecount; + inst->Dx = ml->data+1*pnodecount; + inst->v_unused = ml->data+2*pnodecount; + inst->g_unused = ml->data+3*pnodecount; + } + + + + static void nrn_alloc_leonhard(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + /** initialize channel */ + void nrn_init_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->global->x0; + inst->x[id] = 42.0; + } + } + } + + + /** update state */ + void nrn_state_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->x[id] + (1.0 - exp(nt->_dt * ( -1.0))) * ( -(0.0) / ( -1.0) - inst->x[id]); + } + } + + + /** register channel with the simulator */ + void _leonhard_reg() { + + int mech_type = nrn_get_mechtype("leonhard"); + leonhard_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nullptr, nrn_state_leonhard, nrn_init_leonhard, nrn_private_constructor_leonhard, nrn_private_destructor_leonhard, first_pointer_var_index(), 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/cnexp_scalar/neuron/leonhard.cpp b/cnexp_scalar/neuron/leonhard.cpp new file mode 100644 index 0000000..15e225d --- /dev/null +++ b/cnexp_scalar/neuron/leonhard.cpp @@ -0,0 +1,208 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 0; +static constexpr auto number_of_floating_point_variables = 4; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +Prop* hoc_getdata_range(int type); + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + 0, + "x_leonhard", + 0, + 0 + }; + + + /* NEURON global variables */ + static neuron::container::field_index _slist1[1], _dlist1[1]; + static int mech_type; + static Prop* _extcall_prop; + /* _prop_id kind of shadows _extcall_prop to allow validity checking. */ + static _nrn_non_owning_id_without_container _prop_id{}; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* x{}; + double* Dx{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + static leonhard_Instance make_instance_leonhard(_nrn_mechanism_cache_range& _ml) { + return leonhard_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>(), + _ml.template fpfield_ptr<2>(), + _ml.template fpfield_ptr<3>() + }; + } + + + static void nrn_alloc_leonhard(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 4); + /*initialize range parameters*/ + } + + + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + _extcall_prop = _prop; + _prop_id = _nrn_get_prop_id(_prop); + } + static void _hoc_setdata() { + Prop *_prop = hoc_getdata_range(mech_type); + _setdata(_prop); + hoc_retpushx(1.); + } + /* Mechanism procedures and functions */ + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {"setdata_leonhard", _hoc_setdata}, + {0, 0} + }; + static NPyDirectMechFunc npy_direct_func_proc[] = { + }; + + + void nrn_init_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = 42.0; + } + } + + + void nrn_state_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = inst.x[id] + (1.0 - exp(_nt->_dt * ( -1.0))) * ( -(0.0) / ( -1.0) - inst.x[id]); + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + /* x */ + _slist1[0] = {0, 0}; + /* Dx */ + _dlist1[0] = {1, 0}; + } + + + /** register channel with the simulator */ + extern "C" void _leonhard_reg() { + _initlists(); + + + + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nrn_jacob_leonhard, nrn_state_leonhard, nrn_init_leonhard, hoc_nrnpointerindex, 1); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"x"} /* 0 */, + _nrn_mechanism_field{"Dx"} /* 1 */, + _nrn_mechanism_field{"v_unused"} /* 2 */, + _nrn_mechanism_field{"g_unused"} /* 3 */ + ); + + hoc_register_prop_size(mech_type, 4, 0); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + hoc_register_npy_direct(mech_type, npy_direct_func_proc); + } +} diff --git a/func_proc/coreneuron/func_proc.cpp b/func_proc/coreneuron/func_proc.cpp new file mode 100644 index 0000000..9b019fb --- /dev/null +++ b/func_proc/coreneuron/func_proc.cpp @@ -0,0 +1,285 @@ +/********************************************************* +Model Name : test_func_proc +Filename : func_proc.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_func_proc", + 0, + "x_test_func_proc", + 0, + 0, + 0 + }; + + + /** all global variables */ + struct test_func_proc_Store { + int reset{}; + int mech_type{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_func_proc_Store test_func_proc_global; + + + /** all mechanism instance variables and global variables */ + struct test_func_proc_Instance { + double* x{}; + double* v_unused{}; + test_func_proc_Store* global{&test_func_proc_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 2; + } + + + static inline int int_variables_size() { + return 0; + } + + + static inline int get_mech_type() { + return test_func_proc_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_test_func_proc(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new test_func_proc_Instance{}; + assert(inst->global == &test_func_proc_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(test_func_proc_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_test_func_proc(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_func_proc_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_func_proc_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_func_proc_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_func_proc_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->x = ml->data+0*pnodecount; + inst->v_unused = ml->data+1*pnodecount; + } + + + + static void nrn_alloc_test_func_proc(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_test_func_proc(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_test_func_proc(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + inline double get_a_42_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a); + inline int set_x_42_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v); + inline int set_x_a_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a); + inline int set_a_x_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v); + + + inline int set_x_42_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v) { + int ret_set_x_42 = 0; + set_x_a_test_func_proc(id, pnodecount, inst, data, indexes, thread, nt, v, 42.0); + return ret_set_x_42; + } + + + inline int set_x_a_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a) { + int ret_set_x_a = 0; + inst->x[id] = a; + return ret_set_x_a; + } + + + inline int set_a_x_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v) { + int ret_set_a_x = 0; + double a; + a = inst->x[id]; + return ret_set_a_x; + } + + + inline double get_a_42_test_func_proc(int id, int pnodecount, test_func_proc_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a) { + double ret_get_a_42 = 0.0; + ret_get_a_42 = a + 42.0; + return ret_get_a_42; + } + + + /** initialize channel */ + void nrn_init_test_func_proc(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + } + + + /** register channel with the simulator */ + void _func_proc_reg() { + + int mech_type = nrn_get_mechtype("test_func_proc"); + test_func_proc_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + register_mech(mechanism_info, nrn_alloc_test_func_proc, nullptr, nullptr, nullptr, nrn_init_test_func_proc, nrn_private_constructor_test_func_proc, nrn_private_destructor_test_func_proc, first_pointer_var_index(), 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/func_proc/neuron/func_proc.cpp b/func_proc/neuron/func_proc.cpp new file mode 100644 index 0000000..6168482 --- /dev/null +++ b/func_proc/neuron/func_proc.cpp @@ -0,0 +1,369 @@ +/********************************************************* +Model Name : test_func_proc +Filename : func_proc.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 0; +static constexpr auto number_of_floating_point_variables = 2; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +Prop* hoc_getdata_range(int type); + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_func_proc", + 0, + "x_test_func_proc", + 0, + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static Prop* _extcall_prop; + /* _prop_id kind of shadows _extcall_prop to allow validity checking. */ + static _nrn_non_owning_id_without_container _prop_id{}; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct test_func_proc_Store { + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_func_proc_Store test_func_proc_global; + + + /** all mechanism instance variables and global variables */ + struct test_func_proc_Instance { + double* x{}; + double* v_unused{}; + test_func_proc_Store* global{&test_func_proc_global}; + }; + + + static test_func_proc_Instance make_instance_test_func_proc(_nrn_mechanism_cache_range& _ml) { + return test_func_proc_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>() + }; + } + + + static void nrn_alloc_test_func_proc(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 2); + /*initialize range parameters*/ + } + + + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + _extcall_prop = _prop; + _prop_id = _nrn_get_prop_id(_prop); + } + static void _hoc_setdata() { + Prop *_prop = hoc_getdata_range(mech_type); + _setdata(_prop); + hoc_retpushx(1.); + } + /* Mechanism procedures and functions */ + inline double get_a_42_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a); + inline int set_x_42_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt); + inline int set_x_a_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a); + inline int set_a_x_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt); + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + static void _hoc_set_x_42(void); + static void _hoc_set_x_a(void); + static void _hoc_set_a_x(void); + static void _hoc_get_a_42(void); + static double _npy_set_x_42(Prop*); + static double _npy_set_x_a(Prop*); + static double _npy_set_a_x(Prop*); + static double _npy_get_a_42(Prop*); + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {"setdata_test_func_proc", _hoc_setdata}, + {"set_x_42_test_func_proc", _hoc_set_x_42}, + {"set_x_a_test_func_proc", _hoc_set_x_a}, + {"set_a_x_test_func_proc", _hoc_set_a_x}, + {"get_a_42_test_func_proc", _hoc_get_a_42}, + {0, 0} + }; + static NPyDirectMechFunc npy_direct_func_proc[] = { + {"set_x_42", _npy_set_x_42}, + {"set_x_a", _npy_set_x_a}, + {"set_a_x", _npy_set_a_x}, + {"get_a_42", _npy_get_a_42}, + }; + static void _hoc_set_x_42(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + if (!_prop_id) { + hoc_execerror("No data for set_x_42_test_func_proc. Requires prior call to setdata_test_func_proc and that the specified mechanism instance still be in existence.", NULL); + } + Prop* _local_prop = _extcall_prop; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_x_42_test_func_proc(_ml, id, _ppvar, _thread, _nt); + hoc_retpushx(_r); + } + static double _npy_set_x_42(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_x_42_test_func_proc(_ml, id, _ppvar, _thread, _nt); + return(_r); + } + static void _hoc_set_x_a(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + if (!_prop_id) { + hoc_execerror("No data for set_x_a_test_func_proc. Requires prior call to setdata_test_func_proc and that the specified mechanism instance still be in existence.", NULL); + } + Prop* _local_prop = _extcall_prop; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_x_a_test_func_proc(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + hoc_retpushx(_r); + } + static double _npy_set_x_a(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_x_a_test_func_proc(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + static void _hoc_set_a_x(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + if (!_prop_id) { + hoc_execerror("No data for set_a_x_test_func_proc. Requires prior call to setdata_test_func_proc and that the specified mechanism instance still be in existence.", NULL); + } + Prop* _local_prop = _extcall_prop; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_a_x_test_func_proc(_ml, id, _ppvar, _thread, _nt); + hoc_retpushx(_r); + } + static double _npy_set_a_x(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = 1.; + set_a_x_test_func_proc(_ml, id, _ppvar, _thread, _nt); + return(_r); + } + static void _hoc_get_a_42(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + Prop* _local_prop = _prop_id ? _extcall_prop : nullptr; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = get_a_42_test_func_proc(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + hoc_retpushx(_r); + } + static double _npy_get_a_42(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + _r = get_a_42_test_func_proc(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + + + inline int set_x_42_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt) { + auto inst = make_instance_test_func_proc(*_ml); + int ret_set_x_42 = 0; + set_x_a_test_func_proc(_ml, id, _ppvar, _thread, _nt, 42.0); + return ret_set_x_42; + } + + + inline int set_x_a_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a) { + auto inst = make_instance_test_func_proc(*_ml); + int ret_set_x_a = 0; + inst.x[id] = a; + return ret_set_x_a; + } + + + inline int set_a_x_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt) { + auto inst = make_instance_test_func_proc(*_ml); + int ret_set_a_x = 0; + double a; + a = inst.x[id]; + return ret_set_a_x; + } + + + inline double get_a_42_test_func_proc(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a) { + auto inst = make_instance_test_func_proc(*_ml); + double ret_get_a_42 = 0.0; + ret_get_a_42 = a + 42.0; + return ret_get_a_42; + } + + + void nrn_init_test_func_proc(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_test_func_proc(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_test_func_proc(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _func_proc_reg() { + _initlists(); + + + + register_mech(mechanism_info, nrn_alloc_test_func_proc, nullptr, nullptr, nullptr, nrn_init_test_func_proc, hoc_nrnpointerindex, 1); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"x"} /* 0 */, + _nrn_mechanism_field{"v_unused"} /* 1 */ + ); + + hoc_register_prop_size(mech_type, 2, 0); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + hoc_register_npy_direct(mech_type, npy_direct_func_proc); + } +} diff --git a/func_proc_pnt/coreneuron/func_proc_pnt.cpp b/func_proc_pnt/coreneuron/func_proc_pnt.cpp new file mode 100644 index 0000000..9644888 --- /dev/null +++ b/func_proc_pnt/coreneuron/func_proc_pnt.cpp @@ -0,0 +1,283 @@ +/********************************************************* +Model Name : test_func_proc_pnt +Filename : func_proc_pnt.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_func_proc_pnt", + 0, + "x", + 0, + 0, + 0 + }; + + + /** all global variables */ + struct test_func_proc_pnt_Store { + int point_type{}; + int reset{}; + int mech_type{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_func_proc_pnt_Store test_func_proc_pnt_global; + + + /** all mechanism instance variables and global variables */ + struct test_func_proc_pnt_Instance { + double* x{}; + double* v_unused{}; + const double* node_area{}; + const int* point_process{}; + test_func_proc_pnt_Store* global{&test_func_proc_pnt_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 2; + } + + + static inline int int_variables_size() { + return 2; + } + + + static inline int get_mech_type() { + return test_func_proc_pnt_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_test_func_proc_pnt(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new test_func_proc_pnt_Instance{}; + assert(inst->global == &test_func_proc_pnt_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(test_func_proc_pnt_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_test_func_proc_pnt(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_func_proc_pnt_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_func_proc_pnt_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_func_proc_pnt_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_func_proc_pnt_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->x = ml->data+0*pnodecount; + inst->v_unused = ml->data+1*pnodecount; + inst->node_area = nt->_data; + inst->point_process = ml->pdata; + } + + + + static void nrn_alloc_test_func_proc_pnt(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_test_func_proc_pnt(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_test_func_proc_pnt(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + inline double get_a_42_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a); + inline int set_x_42_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v); + inline int set_x_a_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a); + + + inline int set_x_42_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v) { + int ret_set_x_42 = 0; + inst->x[id] = 42.0; + return ret_set_x_42; + } + + + inline int set_x_a_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a) { + int ret_set_x_a = 0; + inst->x[id] = a; + return ret_set_x_a; + } + + + inline double get_a_42_test_func_proc_pnt(int id, int pnodecount, test_func_proc_pnt_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double a) { + double ret_get_a_42 = 0.0; + ret_get_a_42 = a + 42.0; + return ret_get_a_42; + } + + + /** initialize channel */ + void nrn_init_test_func_proc_pnt(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + } + + + /** register channel with the simulator */ + void _func_proc_pnt_reg() { + + int mech_type = nrn_get_mechtype("test_func_proc_pnt"); + test_func_proc_pnt_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + point_register_mech(mechanism_info, nrn_alloc_test_func_proc_pnt, nullptr, nullptr, nullptr, nrn_init_test_func_proc_pnt, nrn_private_constructor_test_func_proc_pnt, nrn_private_destructor_test_func_proc_pnt, first_pointer_var_index(), nullptr, nullptr, 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/func_proc_pnt/neuron/func_proc_pnt.cpp b/func_proc_pnt/neuron/func_proc_pnt.cpp new file mode 100644 index 0000000..9ba13ea --- /dev/null +++ b/func_proc_pnt/neuron/func_proc_pnt.cpp @@ -0,0 +1,305 @@ +/********************************************************* +Model Name : test_func_proc_pnt +Filename : func_proc_pnt.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 2; +static constexpr auto number_of_floating_point_variables = 2; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +extern Prop* nrn_point_prop_; + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_func_proc_pnt", + 0, + "x", + 0, + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static int _pointtype; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct test_func_proc_pnt_Store { + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_func_proc_pnt_Store test_func_proc_pnt_global; + + + /** all mechanism instance variables and global variables */ + struct test_func_proc_pnt_Instance { + double* x{}; + double* v_unused{}; + const double* const* node_area{}; + test_func_proc_pnt_Store* global{&test_func_proc_pnt_global}; + }; + + + static test_func_proc_pnt_Instance make_instance_test_func_proc_pnt(_nrn_mechanism_cache_range& _ml) { + return test_func_proc_pnt_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>(), + _ml.template dptr_field_ptr<0>() + }; + } + + + static void nrn_alloc_test_func_proc_pnt(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + if (nrn_point_prop_) { + _nrn_mechanism_access_alloc_seq(_prop) = _nrn_mechanism_access_alloc_seq(nrn_point_prop_); + _ppvar = _nrn_mechanism_access_dparam(nrn_point_prop_); + } else { + _ppvar = nrn_prop_datum_alloc(mech_type, 2, _prop); + _nrn_mechanism_access_dparam(_prop) = _ppvar; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 2); + /*initialize range parameters*/ + } + _nrn_mechanism_access_dparam(_prop) = _ppvar; + } + + + /* Point Process specific functions */ + static void* _hoc_create_pnt(Object* _ho) { + return create_point_process(_pointtype, _ho); + } + static void _hoc_destroy_pnt(void* _vptr) { + destroy_point_process(_vptr); + } + static double _hoc_loc_pnt(void* _vptr) { + return loc_point_process(_pointtype, _vptr); + } + static double _hoc_has_loc(void* _vptr) { + return has_loc_point(_vptr); + } + static double _hoc_get_loc_pnt(void* _vptr) { + return (get_loc_point_process(_vptr)); + } + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + } + static void _hoc_setdata(void* _vptr) { + Prop* _prop; + _prop = ((Point_process*)_vptr)->prop; + _setdata(_prop); + } + /* Mechanism procedures and functions */ + inline double get_a_42_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a); + inline int set_x_42_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt); + inline int set_x_a_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a); + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + static double _hoc_set_x_42(void*); + static double _hoc_set_x_a(void*); + static double _hoc_get_a_42(void*); + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {0, 0} + }; + static Member_func _member_func[] = { + {"loc", _hoc_loc_pnt}, + {"has_loc", _hoc_has_loc}, + {"get_loc", _hoc_get_loc_pnt}, + {"set_x_42", _hoc_set_x_42}, + {"set_x_a", _hoc_set_x_a}, + {"get_a_42", _hoc_get_a_42}, + {0, 0} + }; + static double _hoc_set_x_42(void* _vptr) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + auto* const _pnt = static_cast(_vptr); + auto* const _p = _pnt->prop; + if (!_p) { + hoc_execerror("POINT_PROCESS data instance not valid", NULL); + } + _nrn_mechanism_cache_instance _ml_real{_p}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_p); + _thread = _extcall_thread.data(); + _nt = static_cast(_pnt->_vnt); + _r = 1.; + set_x_42_test_func_proc_pnt(_ml, id, _ppvar, _thread, _nt); + return(_r); + } + static double _hoc_set_x_a(void* _vptr) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + auto* const _pnt = static_cast(_vptr); + auto* const _p = _pnt->prop; + if (!_p) { + hoc_execerror("POINT_PROCESS data instance not valid", NULL); + } + _nrn_mechanism_cache_instance _ml_real{_p}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_p); + _thread = _extcall_thread.data(); + _nt = static_cast(_pnt->_vnt); + _r = 1.; + set_x_a_test_func_proc_pnt(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + static double _hoc_get_a_42(void* _vptr) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + auto* const _pnt = static_cast(_vptr); + auto* const _p = _pnt->prop; + if (!_p) { + hoc_execerror("POINT_PROCESS data instance not valid", NULL); + } + _nrn_mechanism_cache_instance _ml_real{_p}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_p); + _thread = _extcall_thread.data(); + _nt = static_cast(_pnt->_vnt); + _r = get_a_42_test_func_proc_pnt(_ml, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + + + inline int set_x_42_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt) { + auto inst = make_instance_test_func_proc_pnt(*_ml); + int ret_set_x_42 = 0; + inst.x[id] = 42.0; + return ret_set_x_42; + } + + + inline int set_x_a_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a) { + auto inst = make_instance_test_func_proc_pnt(*_ml); + int ret_set_x_a = 0; + inst.x[id] = a; + return ret_set_x_a; + } + + + inline double get_a_42_test_func_proc_pnt(_nrn_mechanism_cache_range* _ml, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double a) { + auto inst = make_instance_test_func_proc_pnt(*_ml); + double ret_get_a_42 = 0.0; + ret_get_a_42 = a + 42.0; + return ret_get_a_42; + } + + + void nrn_init_test_func_proc_pnt(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_test_func_proc_pnt(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_test_func_proc_pnt(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _func_proc_pnt_reg() { + _initlists(); + + + + _pointtype = point_register_mech(mechanism_info, nrn_alloc_test_func_proc_pnt, nullptr, nullptr, nullptr, nrn_init_test_func_proc_pnt, hoc_nrnpointerindex, 1, _hoc_create_pnt, _hoc_destroy_pnt, _member_func); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"x"} /* 0 */, + _nrn_mechanism_field{"v_unused"} /* 1 */, + _nrn_mechanism_field{"node_area", "area"} /* 0 */, + _nrn_mechanism_field{"point_process", "pntproc"} /* 1 */ + ); + + hoc_register_prop_size(mech_type, 2, 2); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + } +} diff --git a/global_breakpoint/coreneuron/leonhard.cpp b/global_breakpoint/coreneuron/leonhard.cpp new file mode 100644 index 0000000..2281fa5 --- /dev/null +++ b/global_breakpoint/coreneuron/leonhard.cpp @@ -0,0 +1,283 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + 0, + "x_leonhard", + 0, + 0 + }; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + int reset{}; + int mech_type{}; + double c{2}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* x{}; + double* Dx{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {"c_leonhard", &leonhard_global.c}, + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 4; + } + + + static inline int int_variables_size() { + return 0; + } + + + static inline int get_mech_type() { + return leonhard_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new leonhard_Instance{}; + assert(inst->global == &leonhard_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(leonhard_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &leonhard_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(leonhard_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->x = ml->data+0*pnodecount; + inst->Dx = ml->data+1*pnodecount; + inst->v_unused = ml->data+2*pnodecount; + inst->g_unused = ml->data+3*pnodecount; + } + + + + static void nrn_alloc_leonhard(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_leonhard(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + /** initialize channel */ + void nrn_init_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->global->x0; + inst->x[id] = 42.0; + } + } + } + + + /** update state */ + void nrn_state_leonhard(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + inst->x[id] = inst->global->c; + } + } + + + /** register channel with the simulator */ + void _leonhard_reg() { + + int mech_type = nrn_get_mechtype("leonhard"); + leonhard_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nullptr, nrn_state_leonhard, nrn_init_leonhard, nrn_private_constructor_leonhard, nrn_private_destructor_leonhard, first_pointer_var_index(), 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/global_breakpoint/neuron/leonhard.cpp b/global_breakpoint/neuron/leonhard.cpp new file mode 100644 index 0000000..8b0f021 --- /dev/null +++ b/global_breakpoint/neuron/leonhard.cpp @@ -0,0 +1,205 @@ +/********************************************************* +Model Name : leonhard +Filename : leonhard.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 0; +static constexpr auto number_of_floating_point_variables = 4; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +Prop* hoc_getdata_range(int type); + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "leonhard", + 0, + 0, + "x_leonhard", + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static Prop* _extcall_prop; + /* _prop_id kind of shadows _extcall_prop to allow validity checking. */ + static _nrn_non_owning_id_without_container _prop_id{}; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct leonhard_Store { + double x0{}; + double c{2}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + leonhard_Store leonhard_global; + + + /** all mechanism instance variables and global variables */ + struct leonhard_Instance { + double* x{}; + double* Dx{}; + double* v_unused{}; + double* g_unused{}; + leonhard_Store* global{&leonhard_global}; + }; + + + static leonhard_Instance make_instance_leonhard(_nrn_mechanism_cache_range& _ml) { + return leonhard_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>(), + _ml.template fpfield_ptr<2>(), + _ml.template fpfield_ptr<3>() + }; + } + + + static void nrn_alloc_leonhard(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 4); + /*initialize range parameters*/ + } + + + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + _extcall_prop = _prop; + _prop_id = _nrn_get_prop_id(_prop); + } + static void _hoc_setdata() { + Prop *_prop = hoc_getdata_range(mech_type); + _setdata(_prop); + hoc_retpushx(1.); + } + /* Mechanism procedures and functions */ + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {"c_leonhard", &leonhard_global.c}, + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {"setdata_leonhard", _hoc_setdata}, + {0, 0} + }; + static NPyDirectMechFunc npy_direct_func_proc[] = { + }; + + + void nrn_init_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = 42.0; + } + } + + + void nrn_state_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_leonhard(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + inst.x[id] = inst.global->c; + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_leonhard(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _leonhard_reg() { + _initlists(); + + + + register_mech(mechanism_info, nrn_alloc_leonhard, nullptr, nrn_jacob_leonhard, nrn_state_leonhard, nrn_init_leonhard, hoc_nrnpointerindex, 1); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"x"} /* 0 */, + _nrn_mechanism_field{"Dx"} /* 1 */, + _nrn_mechanism_field{"v_unused"} /* 2 */, + _nrn_mechanism_field{"g_unused"} /* 3 */ + ); + + hoc_register_prop_size(mech_type, 4, 0); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + hoc_register_npy_direct(mech_type, npy_direct_func_proc); + } +} diff --git a/parameter/coreneuron/test_parameter.cpp b/parameter/coreneuron/test_parameter.cpp new file mode 100644 index 0000000..34b2354 --- /dev/null +++ b/parameter/coreneuron/test_parameter.cpp @@ -0,0 +1,257 @@ +/********************************************************* +Model Name : test_parameter +Filename : test_parameter.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_parameter", + "x", + 0, + 0, + 0, + 0 + }; + + + /** all global variables */ + struct test_parameter_Store { + int point_type{}; + int reset{}; + int mech_type{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_parameter_Store test_parameter_global; + + + /** all mechanism instance variables and global variables */ + struct test_parameter_Instance { + const double* x{}; + double* v_unused{}; + const double* node_area{}; + const int* point_process{}; + test_parameter_Store* global{&test_parameter_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 2; + } + + + static inline int int_variables_size() { + return 2; + } + + + static inline int get_mech_type() { + return test_parameter_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_test_parameter(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new test_parameter_Instance{}; + assert(inst->global == &test_parameter_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(test_parameter_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_test_parameter(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_parameter_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_parameter_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_parameter_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_parameter_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->x = ml->data+0*pnodecount; + inst->v_unused = ml->data+1*pnodecount; + inst->node_area = nt->_data; + inst->point_process = ml->pdata; + } + + + + static void nrn_alloc_test_parameter(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_test_parameter(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_test_parameter(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + /** initialize channel */ + void nrn_init_test_parameter(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + } + + + /** register channel with the simulator */ + void _test_parameter_reg() { + + int mech_type = nrn_get_mechtype("test_parameter"); + test_parameter_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + point_register_mech(mechanism_info, nrn_alloc_test_parameter, nullptr, nullptr, nullptr, nrn_init_test_parameter, nrn_private_constructor_test_parameter, nrn_private_destructor_test_parameter, first_pointer_var_index(), nullptr, nullptr, 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/parameter/neuron/test_parameter.cpp b/parameter/neuron/test_parameter.cpp new file mode 100644 index 0000000..212c5d2 --- /dev/null +++ b/parameter/neuron/test_parameter.cpp @@ -0,0 +1,214 @@ +/********************************************************* +Model Name : test_parameter +Filename : test_parameter.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 2; +static constexpr auto number_of_floating_point_variables = 2; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +extern Prop* nrn_point_prop_; + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_parameter", + "x", + 0, + 0, + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static int _pointtype; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct test_parameter_Store { + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_parameter_Store test_parameter_global; + + + /** all mechanism instance variables and global variables */ + struct test_parameter_Instance { + double* x{}; + double* v_unused{}; + const double* const* node_area{}; + test_parameter_Store* global{&test_parameter_global}; + }; + + + static test_parameter_Instance make_instance_test_parameter(_nrn_mechanism_cache_range& _ml) { + return test_parameter_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>(), + _ml.template dptr_field_ptr<0>() + }; + } + + + static void nrn_alloc_test_parameter(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + if (nrn_point_prop_) { + _nrn_mechanism_access_alloc_seq(_prop) = _nrn_mechanism_access_alloc_seq(nrn_point_prop_); + _ppvar = _nrn_mechanism_access_dparam(nrn_point_prop_); + } else { + _ppvar = nrn_prop_datum_alloc(mech_type, 2, _prop); + _nrn_mechanism_access_dparam(_prop) = _ppvar; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 2); + /*initialize range parameters*/ + _ml->template fpfield<0>(_iml) = 42; /* x */ + } + _nrn_mechanism_access_dparam(_prop) = _ppvar; + } + + + /* Point Process specific functions */ + static void* _hoc_create_pnt(Object* _ho) { + return create_point_process(_pointtype, _ho); + } + static void _hoc_destroy_pnt(void* _vptr) { + destroy_point_process(_vptr); + } + static double _hoc_loc_pnt(void* _vptr) { + return loc_point_process(_pointtype, _vptr); + } + static double _hoc_has_loc(void* _vptr) { + return has_loc_point(_vptr); + } + static double _hoc_get_loc_pnt(void* _vptr) { + return (get_loc_point_process(_vptr)); + } + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + } + static void _hoc_setdata(void* _vptr) { + Prop* _prop; + _prop = ((Point_process*)_vptr)->prop; + _setdata(_prop); + } + /* Mechanism procedures and functions */ + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {0, 0} + }; + static Member_func _member_func[] = { + {"loc", _hoc_loc_pnt}, + {"has_loc", _hoc_has_loc}, + {"get_loc", _hoc_get_loc_pnt}, + {0, 0} + }; + + + void nrn_init_test_parameter(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_test_parameter(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_test_parameter(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _test_parameter_reg() { + _initlists(); + + + + _pointtype = point_register_mech(mechanism_info, nrn_alloc_test_parameter, nullptr, nullptr, nullptr, nrn_init_test_parameter, hoc_nrnpointerindex, 1, _hoc_create_pnt, _hoc_destroy_pnt, _member_func); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"x"} /* 0 */, + _nrn_mechanism_field{"v_unused"} /* 1 */, + _nrn_mechanism_field{"node_area", "area"} /* 0 */, + _nrn_mechanism_field{"point_process", "pntproc"} /* 1 */ + ); + + hoc_register_prop_size(mech_type, 2, 2); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + } +} diff --git a/point_process/coreneuron/test_pp.cpp b/point_process/coreneuron/test_pp.cpp new file mode 100644 index 0000000..1496d79 --- /dev/null +++ b/point_process/coreneuron/test_pp.cpp @@ -0,0 +1,254 @@ +/********************************************************* +Model Name : test_pp +Filename : test_pp.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_pp", + 0, + 0, + 0, + 0 + }; + + + /** all global variables */ + struct test_pp_Store { + int point_type{}; + int reset{}; + int mech_type{}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_pp_Store test_pp_global; + + + /** all mechanism instance variables and global variables */ + struct test_pp_Instance { + double* v_unused{}; + const double* node_area{}; + const int* point_process{}; + test_pp_Store* global{&test_pp_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 1; + } + + + static inline int int_variables_size() { + return 2; + } + + + static inline int get_mech_type() { + return test_pp_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_test_pp(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new test_pp_Instance{}; + assert(inst->global == &test_pp_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(test_pp_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_test_pp(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_pp_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_pp_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &test_pp_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(test_pp_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->v_unused = ml->data+0*pnodecount; + inst->node_area = nt->_data; + inst->point_process = ml->pdata; + } + + + + static void nrn_alloc_test_pp(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_test_pp(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_test_pp(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + /** initialize channel */ + void nrn_init_test_pp(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + } + + + /** register channel with the simulator */ + void _test_pp_reg() { + + int mech_type = nrn_get_mechtype("test_pp"); + test_pp_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + point_register_mech(mechanism_info, nrn_alloc_test_pp, nullptr, nullptr, nullptr, nrn_init_test_pp, nrn_private_constructor_test_pp, nrn_private_destructor_test_pp, first_pointer_var_index(), nullptr, nullptr, 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/point_process/neuron/test_pp.cpp b/point_process/neuron/test_pp.cpp new file mode 100644 index 0000000..52c89c5 --- /dev/null +++ b/point_process/neuron/test_pp.cpp @@ -0,0 +1,209 @@ +/********************************************************* +Model Name : test_pp +Filename : test_pp.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 2; +static constexpr auto number_of_floating_point_variables = 1; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +extern Prop* nrn_point_prop_; + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "test_pp", + 0, + 0, + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static int _pointtype; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct test_pp_Store { + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + test_pp_Store test_pp_global; + + + /** all mechanism instance variables and global variables */ + struct test_pp_Instance { + double* v_unused{}; + const double* const* node_area{}; + test_pp_Store* global{&test_pp_global}; + }; + + + static test_pp_Instance make_instance_test_pp(_nrn_mechanism_cache_range& _ml) { + return test_pp_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template dptr_field_ptr<0>() + }; + } + + + static void nrn_alloc_test_pp(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + if (nrn_point_prop_) { + _nrn_mechanism_access_alloc_seq(_prop) = _nrn_mechanism_access_alloc_seq(nrn_point_prop_); + _ppvar = _nrn_mechanism_access_dparam(nrn_point_prop_); + } else { + _ppvar = nrn_prop_datum_alloc(mech_type, 2, _prop); + _nrn_mechanism_access_dparam(_prop) = _ppvar; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 1); + /*initialize range parameters*/ + } + _nrn_mechanism_access_dparam(_prop) = _ppvar; + } + + + /* Point Process specific functions */ + static void* _hoc_create_pnt(Object* _ho) { + return create_point_process(_pointtype, _ho); + } + static void _hoc_destroy_pnt(void* _vptr) { + destroy_point_process(_vptr); + } + static double _hoc_loc_pnt(void* _vptr) { + return loc_point_process(_pointtype, _vptr); + } + static double _hoc_has_loc(void* _vptr) { + return has_loc_point(_vptr); + } + static double _hoc_get_loc_pnt(void* _vptr) { + return (get_loc_point_process(_vptr)); + } + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + } + static void _hoc_setdata(void* _vptr) { + Prop* _prop; + _prop = ((Point_process*)_vptr)->prop; + _setdata(_prop); + } + /* Mechanism procedures and functions */ + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {0, 0} + }; + static Member_func _member_func[] = { + {"loc", _hoc_loc_pnt}, + {"has_loc", _hoc_has_loc}, + {"get_loc", _hoc_get_loc_pnt}, + {0, 0} + }; + + + void nrn_init_test_pp(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_test_pp(_lmr); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_test_pp(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) {} + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _test_pp_reg() { + _initlists(); + + + + _pointtype = point_register_mech(mechanism_info, nrn_alloc_test_pp, nullptr, nullptr, nullptr, nrn_init_test_pp, hoc_nrnpointerindex, 1, _hoc_create_pnt, _hoc_destroy_pnt, _member_func); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"v_unused"} /* 0 */, + _nrn_mechanism_field{"node_area", "area"} /* 0 */, + _nrn_mechanism_field{"point_process", "pntproc"} /* 1 */ + ); + + hoc_register_prop_size(mech_type, 1, 2); + hoc_register_dparam_semantics(mech_type, 0, "area"); + hoc_register_dparam_semantics(mech_type, 1, "pntproc"); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + } +}