NEURON
mech_mapping.cpp
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2021 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================
7 */
8 
9 
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <map>
14 
20 namespace coreneuron {
21 using Offset = size_t;
22 using MechId = int;
23 // we use char* because it works with nullptrs and we do not need copies of the keys
24 using VariableName = const char*;
25 
26 
27 /*
28  * Return the index to mechanism variable based Original input files are organized in AoS
29  */
30 int get_data_index(int node_index, int variable_index, int mtype, Memb_list* ml) {
31  int layout = corenrn.get_mech_data_layout()[mtype];
32  nrn_assert(layout == SOA_LAYOUT);
33  return variable_index * ml->_nodecount_padded + node_index;
34 }
35 
36 // comparator for MechNamesMapping
37 struct cmp_str {
38  bool operator()(char const* a, char const* b) const {
39  return std::strcmp(a, b) < 0;
40  }
41 };
42 
43 /*
44  * Structure that map variable names of mechanisms to their value's location (offset) in memory
45  */
46 using MechNamesMapping = std::map<MechId, std::map<VariableName, Offset, cmp_str>>;
48 
49 double* get_var_location_from_var_name(int mech_id,
50  const std::string_view mech_name,
51  const std::string_view variable_name,
52  Memb_list* ml,
53  int node_index) {
54  const auto mech_it = mechNamesMapping.find(mech_id);
55  if (mech_it == mechNamesMapping.end()) {
56  std::cerr << "No variable name mapping exists for mechanism id: " << mech_id << std::endl;
57  nrn_abort(1);
58  }
59 
60  const auto& mech = mech_it->second;
61  auto offset_it = mech.find(variable_name.data());
62  if (offset_it == mech.end()) {
63  // Try fallback with variable_name + "_" + mech_name. Used necessary for i_pas
64  std::string fallback_name = std::string(variable_name) + "_" + std::string(mech_name);
65  offset_it = mech.find(fallback_name.data());
66 
67  if (offset_it == mech.end()) {
68  std::cerr << "No value associated to variable name: '" << variable_name
69  << "' or fallback '" << fallback_name << "'";
70  nrn_abort(1);
71  }
72  }
73 
74  const int ix = get_data_index(node_index, offset_it->second, mech_id, ml);
75  return &(ml->data[ix]);
76 }
77 
78 void register_all_variables_offsets(int mech_id, SerializedNames variable_names) {
79  int idx = 0;
80  int nb_parsed_variables = 0;
81  // I do not know why we loop over only 3 categories
82  int current_category = 1;
83  while (current_category < NB_MECH_VAR_CATEGORIES) {
84  if (variable_names[idx]) {
85  mechNamesMapping[mech_id][variable_names[idx]] = nb_parsed_variables;
86  nb_parsed_variables++;
87  } else {
88  current_category++;
89  }
90  idx++;
91  }
92 }
93 
94 } // namespace coreneuron
int node_index(Section *sec, double x)
returns nearest index to x
Definition: cabcode.cpp:1406
#define SOA_LAYOUT
Definition: data_layout.hpp:11
#define NB_MECH_VAR_CATEGORIES
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
static MechNamesMapping mechNamesMapping
void nrn_abort(int errcode)
Definition: utils.cpp:13
int get_data_index(int node_index, int variable_index, int mtype, Memb_list *ml)
std::map< MechId, std::map< VariableName, Offset, cmp_str > > MechNamesMapping
size_t Offset
double * get_var_location_from_var_name(int mech_id, const std::string_view mech_name, const std::string_view variable_name, Memb_list *ml, int node_index)
const char ** SerializedNames
CoreNeuron corenrn
Definition: multicore.cpp:53
const char * VariableName
void register_all_variables_offsets(int mech_id, SerializedNames variable_names)
#define nrn_assert(x)
assert()-like macro, independent of NDEBUG status
Definition: nrn_assert.h:33
bool operator()(char const *a, char const *b) const