1 #include <../../nrnconf.h>
19 extern void nrn_possible_mismatched_arch(
const char*);
22 #if DARWIN || defined(__linux__)
23 extern const char* path_prefix_to_libnrniv();
29 #include "nrnmpi_def_cinc"
31 #include "nrnmpi_dynam_cinc"
33 #include "nrnmpi_dynam_wrappers.inc"
34 #include "nrnmpi_dynam_stubs.cpp"
36 static void* load_mpi(
const char*
name,
char* mes) {
41 nrn_possible_mismatched_arch(
name);
50 static void* load_nrnmpi(
const char*
name,
char* mes) {
59 for (
i = 0; ftable[
i].name; ++
i) {
68 char* (**p)(size_t) = (
char* (**) (size_t))
dlsym(handle, "p_cxx_char_alloc");
78 char* nrnmpi_load(
int is_python) {
82 pmes =
static_cast<char*
>(malloc(4096));
91 if (
info.dli_fname[0] ==
'/' || strchr(
info.dli_fname,
':')) {
93 "<libmpi> is loaded in the sense the MPI_Initialized has an address\n");
94 handle = load_mpi(
info.dli_fname, pmes + strlen(pmes));
106 sprintf(pmes,
"Try loading libmpi\n");
107 handle = load_mpi(
"libmpi.dylib", pmes + strlen(pmes));
115 const char* mpi_lib_path =
getenv(
"MPI_LIB_NRN_PATH");
117 handle = load_mpi(mpi_lib_path, pmes + strlen(pmes));
119 sprintf(pmes,
"Can not load libmpi.dylib and %s\n", mpi_lib_path);
125 if (
dlsym(handle,
"ompi_mpi_init")) {
127 if (!load_nrnmpi(
"@loader_path/libnrnmpi_ompi.dylib", pmes + strlen(pmes))) {
132 if (!load_nrnmpi(
"@loader_path/libnrnmpi_mpich.dylib", pmes + strlen(pmes))) {
140 "Is openmpi or mpich installed? If not in default location, "
141 "need a LD_LIBRARY_PATH on Linux or DYLD_LIBRARY_PATH on Mac OS. "
142 "On Mac OS, full path to a MPI library can be provided via "
143 "environmental variable MPI_LIB_NRN_PATH\n");
148 sprintf(pmes,
"Try loading msmpi\n");
149 handle = load_mpi(
"msmpi.dll", pmes + strlen(pmes));
152 if (!load_nrnmpi(
"libnrnmpi_msmpi.dll", pmes + strlen(pmes))) {
168 sprintf(pmes,
"Try loading libmpi\n");
169 handle = load_mpi(
"libmpi.so", pmes + strlen(pmes));
174 const char* mpi_lib_path =
getenv(
"MPI_LIB_NRN_PATH");
176 handle = load_mpi(mpi_lib_path, pmes + strlen(pmes));
178 sprintf(pmes,
"Can not load libmpi.so and %s", mpi_lib_path);
184 sprintf(pmes,
"Try loading libmpi and libmpich\n");
185 handle = load_mpi(
"libmpich.so", pmes + strlen(pmes));
193 std::string
error{
"Promoted none of"};
194 auto const promote_to_global = [&
error](
const char* lib) {
197 error =
error +
' ' + lib +
" (" + (dlerr ? dlerr :
"nullptr") +
')';
202 if (!promote_to_global(
"libnrniv.so") &&
203 !promote_to_global(
"libnrniv-without-nvidia.so")) {
204 std::cerr <<
error <<
" to RTLD_GLOBAL" << std::endl;
208 auto const libnrnmpi_prefix = []() -> std::string {
209 if (
const char* nrn_home =
std::getenv(
"NRNHOME")) {
211 return std::string{nrn_home} +
"/lib/";
214 return path_prefix_to_libnrniv();
219 auto const mpi_implementation = [handle] {
220 if (
dlsym(handle,
"ompi_mpi_init")) {
223 }
else if (
dlsym(handle,
"MPI_SGI_vtune_is_running")) {
233 auto const nrn_mpi_library = libnrnmpi_prefix +
"libnrnmpi_" + mpi_implementation +
".so";
235 if (!load_nrnmpi(nrn_mpi_library.c_str(), pmes + strlen(pmes))) {
241 "Is openmpi, mpich, intel-mpi, sgi-mpt etc. installed? If not in default location, "
242 "need a LD_LIBRARY_PATH or MPI_LIB_NRN_PATH.\n");
247 sprintf(pmes + strlen(pmes),
"could not dynamically load libmpi.so or libmpich.so\n");
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
DLFCN_EXPORT void * dlopen(const char *file, int mode)
DLFCN_EXPORT char * dlerror(void)
DLFCN_EXPORT int dladdr(const void *addr, Dl_info *info)
DLFCN_NOINLINE DLFCN_EXPORT void * dlsym(void *handle, const char *name)
#define error(err_num, fn_name)
char * cxx_char_alloc(size_t sz)
char * getenv(const char *s)
std::string corenrn_mpi_library