26 #define RTLD_NODELETE 0
40 "CoreNEURON cannot simulate a model that contains extra LinearMechanism or RxD "
46 "CoreNEURON cannot simulate a model that contains the extracellular mechanism",
NULL);
55 "NEURON model internal structures for CoreNEURON are out of date. Make sure call to "
68 std::vector<double>
v;
70 std::sort(
v.begin(),
v.end());
78 for (
const auto off: offsets) {
80 hoc_execerror(
"electrode_offsets must be monotonically non-decreasing",
nullptr);
110 std::vector<size_t> electrode_offsets;
114 "nrnbbcore_register_mapping: arg 6 must be a Vector of electrode offsets.",
115 "Version mismatch: update neurodamus or downgrade NEURON.");
120 electrode_offsets.resize(
n);
122 return static_cast<size_t>(v);
136 Printf(
"Error: Section and Segment mapping vectors should have same size!\n");
144 smap->
sections.assign(sections, sections + nseg);
145 smap->
segments.assign(segments, segments + nseg);
146 smap->
seglfp_factors.assign(seg_lfp_factors, seg_lfp_factors + nlfp);
181 auto*
const pd =
static_cast<double*
>(dh);
186 if (
auto const maybe_index = tml->ml->legacy_index(pd); maybe_index >= 0) {
192 return type == 0 ? 1 : 0;
196 #if defined(HAVE_DLFCN_H)
201 bool is_coreneuron_loaded() {
202 bool is_loaded =
false;
207 is_loaded = fn ==
NULL ? false :
true;
215 void* get_handle_for_lib(std::filesystem::path
const& path) {
221 hoc_execerror(
"Could not dlopen CoreNEURON mechanism library : ", path.string().c_str());
227 void* get_coreneuron_handle() {
229 if (is_coreneuron_loaded()) {
234 std::vector<std::filesystem::path> paths_tried;
235 paths_tried.reserve(3);
238 const char* corenrn_lib = std::getenv(
"CORENEURONLIB");
240 std::filesystem::path
const corenrn_lib_path{corenrn_lib};
241 paths_tried.push_back(corenrn_lib_path);
242 if (std::filesystem::exists(corenrn_lib_path)) {
243 return get_handle_for_lib(corenrn_lib_path);
247 auto const corenrn_lib_name = std::string{neuron::config::shared_library_prefix}
248 .append(
"corenrnmech")
249 .append(neuron::config::shared_library_suffix);
254 auto const corenrn_lib_path = std::filesystem::current_path() /
255 neuron::config::system_processor / corenrn_lib_name;
256 paths_tried.push_back(corenrn_lib_path);
257 if (std::filesystem::exists(corenrn_lib_path)) {
258 return get_handle_for_lib(corenrn_lib_path);
264 std::filesystem::path corenrn_lib_path{
neuron_home};
265 auto const corenrn_internal_lib_name = std::string{neuron::config::shared_library_prefix}
266 .append(
"corenrnmech_internal")
267 .append(neuron::config::shared_library_suffix);
269 (corenrn_lib_path /=
"..") /=
"..";
271 (corenrn_lib_path /=
"lib") /= corenrn_internal_lib_name;
272 paths_tried.push_back(corenrn_lib_path);
273 if (std::filesystem::exists(corenrn_lib_path)) {
274 return get_handle_for_lib(corenrn_lib_path);
277 std::ostringstream oss;
278 oss <<
"Could not find CoreNEURON library, tried:";
279 for (
auto const& path: paths_tried) {
282 throw std::runtime_error(oss.str());
286 void check_coreneuron_compatibility(
void*
handle) {
288 void* cn_version_sym =
dlsym(
handle,
"corenrn_version");
289 if (!cn_version_sym) {
293 const char* cn_bbcore_read_version = (*(
const char* (*) ()) cn_version_sym)();
297 std::stringstream s_path;
299 hoc_execerror(
"Incompatible NEURON and CoreNEURON versions :", s_path.str().c_str());
DLFCN_EXPORT void * dlopen(const char *file, int mode)
DLFCN_EXPORT char * dlerror(void)
DLFCN_EXPORT int dlclose(void *handle)
DLFCN_NOINLINE DLFCN_EXPORT void * dlsym(void *handle, const char *name)
double * hoc_getarg(int narg)
int hoc_is_double_arg(int narg)
IvocVect * vector_arg(int i)
void move(Item *q1, Item *q2, Item *q3)
double * vector_vec(IvocVect *v)
void hoc_execerror(const char *s1, const char *s2)
int vector_capacity(IvocVect *v)
handle_interface< non_owning_identifier< storage > > handle
Non-owning handle to a Mechanism instance.
Model & model()
Access the global Model instance.
data_handle< T > transform(data_handle< T > handle, Transform type)
neuron::model_sorted_token nrn_ensure_model_data_are_sorted()
Ensure neuron::container::* data are sorted.
static void validate_electrode_offsets(const std::vector< size_t > &offsets)
Validate electrode offsets: monotonically non-decreasing.
short * nrn_is_artificial_
void(* nrnthread_v_transfer_)(NrnThread *)
int count_distinct(double *data, int len)
Count number of unique elements in the array.
void nrnbbcore_register_mapping()
For BBP use case, we want to write section-segment mapping to gid_3.dat file.
int nrn_dblpntr2nrncore(neuron::container::data_handle< double > dh, NrnThread &nt, int &type, int &index)
const char * bbcore_write_version
NrnMappingInfo mapinfo
mapping information
int nrndae_list_is_empty()
int const size_t const size_t n
static double unique(void *v)
Compartment mapping information for NrnThread.
void add_sec_mapping(int gid, SecMapping *s)
add section mapping information for given gid if cell is not peviously added, create new cell mapping...
Represent main neuron object computed by single thread.
struct NrnThreadMembList * next
Section to segment mapping.
std::vector< int > segments
list of segments
std::vector< double > seglfp_factors
list of lfp factors associated with each segment
std::vector< size_t > electrode_offsets
Electrode offsets as partial sums (CSR-style).
std::vector< int > sections
list sections associated with each segment
container::Node::storage & node_data()
Access the structure containing the data of all Nodes.
Field for fast_imem calculation.
bool refers_to(Container const &container) const
Query whether this generic handle points to a value from the Tag field of the given container.
std::size_t current_row() const
Get the current logical row number.
int Printf(const char *fmt, Args... args)