NEURON
enginemech.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  * \file
11  * \brief Provides interface function for CoreNEURON mechanism library and NEURON
12  *
13  * libcorenrnmech is a interface library provided to building standalone executable
14  * special-core. Also, it is used by NEURON to run CoreNEURON via dlopen to execute
15  * models via in-memory transfer.
16  */
17 
18 #include <cstdlib>
19 #include <coreneuron/engine.h>
20 #include <string>
21 #include <iostream>
22 
23 namespace coreneuron {
24 
25 /** Mechanism registration function
26  *
27  * If external mechanisms present then use modl_reg function generated
28  * in mod_func.cpp otherwise use empty one.
29  */
30 #ifdef ADDITIONAL_MECHS
31 extern void modl_reg();
32 #else
33 void modl_reg() {}
34 #endif
35 
36 /// variables defined in coreneuron library
37 extern bool nrn_have_gaps;
38 extern bool nrn_use_fast_imem;
39 
40 /// function defined in coreneuron library
41 extern void nrn_cleanup_ion_map();
42 } // namespace coreneuron
43 
44 extern "C" {
45 
46 /// global variables from coreneuron library
47 extern bool corenrn_embedded;
48 extern bool corenrn_file_mode;
49 extern int corenrn_embedded_nthread;
50 
51 /// parse arguments from neuron and prepare new one for coreneuron
52 char* prepare_args(int& argc, char**& argv, std::string& args);
53 
54 /// initialize standard mechanisms from coreneuron
55 void mk_mech_init(int argc, char** argv);
56 
57 /// set openmp threads equal to neuron's pthread
58 void set_openmp_threads(int nthread);
59 
60 /**
61  * Add MPI library loading CLI argument for CoreNEURON
62  *
63  * CoreNEURON requires `--mpi-lib` CLI argument with the
64  * path of library. In case of `solve_core()` call from MOD
65  * file, such CLI argument may not present. In this case, we
66  * additionally check `NRN_CORENRN_MPI_LIB` env variable set
67  * by NEURON.
68  *
69  * @param mpi_lib path of coreneuron MPI library to load
70  * @param args char* argv[] in std::string form
71  */
72 void add_mpi_library_arg(const char* mpi_lib, std::string& args) {
73  std::string corenrn_mpi_lib;
74 
75  // check if user or neuron has provided one
76  if (mpi_lib != nullptr) {
77  corenrn_mpi_lib = std::string(mpi_lib);
78  }
79 
80  // if mpi library is not provided / empty then try to use what
81  // neuron might have detected and set via env var `NRN_CORENRN_MPI_LIB`
82  if (corenrn_mpi_lib.empty()) {
83  char* lib = getenv("NRN_CORENRN_MPI_LIB");
84  if (lib != nullptr) {
85  corenrn_mpi_lib = std::string(lib);
86  }
87  }
88 
89  // add mpi library argument if found
90  if (!corenrn_mpi_lib.empty()) {
91  args.append(" --mpi-lib ");
92  args.append(corenrn_mpi_lib);
93  }
94 }
95 
96 /** Run CoreNEURON in embedded mode with NEURON
97  *
98  * @param nthread Number of Pthreads on NEURON side
99  * @param have_gaps True if gap junctions are used
100  * @param use_mpi True if MPI is used on NEURON side
101  * @param use_fast_imem True if fast imembrance calculation enabled
102  * @param nrn_arg Command line arguments passed by NEURON
103  * @return 1 if embedded mode is used otherwise 0
104  * \todo Change return type semantics
105  */
106 int corenrn_embedded_run(int nthread,
107  int have_gaps,
108  int use_mpi,
109  int use_fast_imem,
110  const char* mpi_lib,
111  const char* nrn_arg,
112  int file_mode) {
113  bool corenrn_skip_write_model_to_disk = false;
114  const std::string corenrn_skip_write_model_to_disk_arg{"--skip-write-model-to-disk"};
115  // If "only_simulate_str" exists in "nrn_arg" then avoid transferring any data between NEURON
116  // and CoreNEURON Instead run the CoreNEURON simulation only with the coredat files provided
117  // "only_simulate_str" is an internal string and shouldn't be made public to the CoreNEURON CLI
118  // options so it is removed from "nrn_arg" first construct all arguments as string
119  std::string filtered_nrn_arg{nrn_arg};
120  const auto ind =
121  static_cast<std::string>(filtered_nrn_arg).find(corenrn_skip_write_model_to_disk_arg);
122  if (ind != std::string::npos) {
123  corenrn_skip_write_model_to_disk = true;
124  filtered_nrn_arg.erase(ind, corenrn_skip_write_model_to_disk_arg.size());
125  }
126  // set coreneuron's internal variable based on neuron arguments
127  corenrn_embedded = !corenrn_skip_write_model_to_disk;
128  corenrn_file_mode = file_mode;
129  corenrn_embedded_nthread = nthread;
130  coreneuron::nrn_have_gaps = have_gaps != 0;
132 
133  // set number of openmp threads
134  set_openmp_threads(nthread);
135 
136  filtered_nrn_arg.insert(0, " coreneuron ");
137  filtered_nrn_arg.append(" --skip-mpi-finalize ");
138 
139  if (use_mpi) {
140  filtered_nrn_arg.append(" --mpi ");
141  }
142 
143  add_mpi_library_arg(mpi_lib, filtered_nrn_arg);
144 
145  // pre-process argumnets from neuron and prepare new for coreneuron
146  int argc;
147  char** argv;
148 
149  char* new_arg = prepare_args(argc, argv, filtered_nrn_arg);
150 
151  // initialize internal arguments
153 
154  // initialize extra arguments built into special-core
155  static bool modl_reg_called = false;
156  if (!modl_reg_called) {
158  modl_reg_called = true;
159  }
160  // run simulation
162 
163  // free temporary string created from prepare_args
164  free(new_arg);
165 
166  // delete array for argv
167  delete[] argv;
168 
169  return corenrn_embedded ? 1 : 0;
170 }
171 }
172 
173 /** Initialize mechanisms and run simulation using CoreNEURON
174  *
175  * NOTE: this type of usage via MOD file exist in neurodamus
176  * where we delete entire model and call coreneuron via file
177  * mode.
178  */
179 int solve_core(int argc, char** argv) {
180  // first construct argument as string
181  std::string args;
182  for (int i = 0; i < argc; i++) {
183  args.append(argv[i]);
184  args.append(" ");
185  }
186 
187  corenrn_file_mode = true;
188 
189  // add mpi library argument
190  add_mpi_library_arg("", args);
191 
192  // pre-process arguments and prepare it fore coreneuron
193  int new_argc;
194  char** new_argv;
195  char* arg_to_free = prepare_args(new_argc, new_argv, args);
196 
197  mk_mech_init(new_argc, new_argv);
199  int ret = run_solve_core(new_argc, new_argv);
200 
202  free(arg_to_free);
203  delete[] new_argv;
204 
205  return ret;
206 }
#define i
Definition: md1redef.h:19
static double use_fast_imem(void *v)
Definition: cvodeobj.cpp:552
int corenrn_embedded_nthread
Definition: nrn_setup.cpp:49
int solve_core(int argc, char **argv)
Initialize mechanisms and run simulation using CoreNEURON.
Definition: enginemech.cpp:179
void set_openmp_threads(int nthread)
set openmp threads equal to neuron's pthread
Definition: main1.cpp:65
int corenrn_embedded_run(int nthread, int have_gaps, int use_mpi, int use_fast_imem, const char *mpi_lib, const char *nrn_arg, int file_mode)
Run CoreNEURON in embedded mode with NEURON.
Definition: enginemech.cpp:106
bool corenrn_file_mode
Definition: nrn_setup.cpp:48
bool corenrn_embedded
global variables from coreneuron library
Definition: nrn_setup.cpp:47
void mk_mech_init(int argc, char **argv)
initialize standard mechanisms from coreneuron
Definition: main1.cpp:438
char * prepare_args(int &argc, char **&argv, std::string &args)
parse arguments from neuron and prepare new one for coreneuron
Definition: main1.cpp:77
void add_mpi_library_arg(const char *mpi_lib, std::string &args)
Add MPI library loading CLI argument for CoreNEURON.
Definition: enginemech.cpp:72
static int argc
Definition: inithoc.cpp:45
static char ** argv
Definition: inithoc.cpp:46
int run_solve_core(int argc, char **argv)
Definition: main1.cpp:492
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
bool nrn_have_gaps
variables defined in coreneuron library
Definition: partrans.cpp:21
bool nrn_use_fast_imem
Definition: fast_imem.cpp:19
void modl_reg()
Mechanism registration function.
Definition: enginemech.cpp:33
void nrn_cleanup_ion_map()
Cleanup global ion map created during mechanism registration.
Definition: nrn_setup.cpp:707
int find(const int, const int, const int, const int, const int)