NEURON
nrnmusic_dynam.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <stdio.h>
3 #include <assert.h>
4 #include <errno.h>
5 #include "oc_ansi.h"
6 #include "nrnmusicapi.h"
7 #include <array>
8 #include <cstdlib>
9 
10 #include "nrnwrap_dlfcn.h"
11 
13 void (*p_nrnmusic_injectlist)(void*, double);
14 void (*p_nrnmusic_init)(int* parg, char*** pargv);
16 
17 #if DARWIN || defined(__linux__)
18 extern const char* path_prefix_to_libnrniv();
19 #else
20 #error MUSIC dynamic loading not implemented for this architecture.
21 #endif
22 
23 static void load_music() {
24  void* handle = nullptr;
25  using const_char_ptr = const char*;
26  // would be nice to figure out path from `which music` but not on
27  // every rank if nhost is large. So demand ...
28  const_char_ptr music_path = const_char_ptr{std::getenv("NRN_LIBMUSIC_PATH")};
29  if (!music_path) {
30  Fprintf(stderr, "No NRN_LIBMUSIC_PATH environment variable for full path to libmusic\n");
31  exit(1);
32  }
33  handle = dlopen(music_path, RTLD_NOW | RTLD_GLOBAL);
34  if (!handle) {
35  Fprintf(stderr, "%s", dlerror());
36  exit(1);
37  }
38 }
39 
40 void nrnmusic_load() {
41  static bool is_loaded{false};
42  if (is_loaded) {
43  return;
44  }
45 
46  load_music();
47 
48  // use nrnmpi/nrnmpi_dynam.cpp strategies to figure out paths.
49  auto const nrnlib_prefix = []() -> std::string {
50  if (const char* nrn_home = std::getenv("NRNHOME")) {
51  // TODO: what about windows path separators?
52  return std::string{nrn_home} + "/lib/";
53  } else {
54  // Use the directory libnrniv.so is in
55  return path_prefix_to_libnrniv();
56  }
57  }();
58 
59  auto const nrnlib_path = [&](std::string_view middle) {
60  std::string name{nrnlib_prefix};
61  name.append(neuron::config::shared_library_prefix);
62  name.append(middle);
63  name.append(neuron::config::shared_library_suffix);
64  return name;
65  };
66  auto const nrnmusic_library = nrnlib_path("nrnmusic");
67 
68  void* handle = dlopen(nrnmusic_library.c_str(), RTLD_NOW | RTLD_GLOBAL);
69  if (!handle) {
70  Fprintf(stderr, "%s\n", dlerror());
71  exit(1);
72  }
73  assert(handle);
74  p_nrnmusic_runtime_phase = (void (*)()) dlsym(handle, "nrnmusic_runtime_phase");
76  p_nrnmusic_injectlist = (void (*)(void*, double)) dlsym(handle, "nrnmusic_injectlist");
78  p_nrnmusic_init = (void (*)(int*, char***)) dlsym(handle, "nrnmusic_init");
80  p_nrnmusic_terminate = (void (*)()) dlsym(handle, "nrnmusic_terminate");
82  is_loaded = true;
83 }
DLFCN_EXPORT void * dlopen(const char *file, int mode)
Definition: dlfcn.c:331
DLFCN_EXPORT char * dlerror(void)
Definition: dlfcn.c:548
DLFCN_NOINLINE DLFCN_EXPORT void * dlsym(void *handle, const char *name)
Definition: dlfcn.c:447
#define RTLD_NOW
Definition: dlfcn.h:47
#define RTLD_GLOBAL
Definition: dlfcn.h:56
#define assert(ex)
Definition: hocassrt.h:24
const char * name
Definition: init.cpp:16
handle_interface< non_owning_identifier< storage > > handle
Non-owning handle to a Mechanism instance.
void(* p_nrnmusic_runtime_phase)()
void(* p_nrnmusic_init)(int *parg, char ***pargv)
void(* p_nrnmusic_terminate)()
static void load_music()
void(* p_nrnmusic_injectlist)(void *, double)
void nrnmusic_load()
HOC interpreter function declarations (included by hocdec.h)
int Fprintf(FILE *stream, const char *fmt, Args... args)
Definition: logger.hpp:8