1 #include <../../nrnconf.h> 16 extern void* dlopen_noerr(
const char*
name,
int mode);
17 #define dlopen dlopen_noerr 18 extern void*
dlsym(
void* handle,
const char*
name);
19 extern int dlclose(
void* handle);
32 extern void nrn_possible_mismatched_arch(
const char*);
35 #if DARWIN || defined(__linux__) 36 extern const char* path_prefix_to_libnrniv();
42 #include "nrnmpi_def_cinc" 44 #include "nrnmpi_dynam_cinc" 46 #include "nrnmpi_dynam_wrappers.inc" 47 #include "nrnmpi_dynam_stubs.cpp" 49 static void* load_mpi(
const char*
name,
char* mes) {
51 void* handle =
dlopen(name, flag);
54 nrn_possible_mismatched_arch(name);
58 sprintf(mes,
"load_mpi: %s successful\n", name);
63 static void* load_nrnmpi(
const char* name,
char* mes) {
66 void* handle =
dlopen(name, flag);
71 sprintf(mes,
"load_nrnmpi: %s successful\n", name);
72 for (i = 0; ftable[
i].name; ++
i) {
73 void*
p =
dlsym(handle, ftable[i].name);
81 char* (**p)(size_t) = (
char* (**)(size_t))
dlsym(handle, "p_cxx_char_alloc");
91 char* nrnmpi_load(
int is_python) {
95 pmes =
static_cast<char*
>(malloc(4096));
99 sprintf(pmes,
"Try loading libmpi\n");
100 handle = load_mpi(
"libmpi.dylib", pmes+strlen(pmes));
107 const char* mpi_lib_path =
getenv(
"MPI_LIB_NRN_PATH");
109 handle = load_mpi(mpi_lib_path, pmes+strlen(pmes));
111 sprintf(pmes,
"Can not load libmpi.dylib and %s\n", mpi_lib_path);
117 if (
dlsym(handle,
"ompi_mpi_init")) {
119 if (!load_nrnmpi(
"@loader_path/libnrnmpi_ompi.dylib", pmes+strlen(pmes))) {
124 if (!load_nrnmpi(
"@loader_path/libnrnmpi_mpich.dylib", pmes+strlen(pmes))) {
131 sprintf(pmes+strlen(pmes),
"Is openmpi or mpich installed? If not in default location, " 132 "need a LD_LIBRARY_PATH on Linux or DYLD_LIBRARY_PATH on Mac OS. " 133 "On Mac OS, full path to a MPI library can be provided via " 134 "environmental variable MPI_LIB_NRN_PATH\n");
138 sprintf(pmes,
"Try loading msmpi\n");
139 handle = load_mpi(
"msmpi.dll", pmes+strlen(pmes));
141 if (!load_nrnmpi(
"libnrnmpi_msmpi.dll", pmes+strlen(pmes))){
156 sprintf(pmes,
"Try loading libmpi\n");
157 handle = load_mpi(
"libmpi.so", pmes+strlen(pmes));
161 const char* mpi_lib_path =
getenv(
"MPI_LIB_NRN_PATH");
163 handle = load_mpi(mpi_lib_path, pmes+strlen(pmes));
165 sprintf(pmes,
"Can not load libmpi.so and %s", mpi_lib_path);
171 sprintf(pmes,
"Try loading libmpi and libmpich\n");
172 handle = load_mpi(
"libmpich.so", pmes+strlen(pmes));
180 std::string
error{
"Promoted none of"};
181 auto const promote_to_global = [&
error](
const char* lib) {
184 error =
error +
' ' + lib +
" (" + (dlerr ? dlerr :
"nullptr") +
')';
189 if(!promote_to_global(
"libnrniv.so") && !promote_to_global(
"libnrniv-without-nvidia.so")) {
190 std::cerr <<
error <<
" to RTLD_GLOBAL" << std::endl;
194 auto const libnrnmpi_prefix = []() -> std::string {
195 if(
const char* nrn_home =
std::getenv(
"NRNHOME")) {
197 return std::string{nrn_home} +
"/lib/";
200 return path_prefix_to_libnrniv();
205 auto const mpi_implementation = [handle] {
206 if (
dlsym(handle,
"ompi_mpi_init")) {
209 }
else if (
dlsym(handle,
"MPI_SGI_vtune_is_running")) {
219 auto const nrn_mpi_library = libnrnmpi_prefix +
"libnrnmpi_" + mpi_implementation +
".so";
221 if (!load_nrnmpi(nrn_mpi_library.c_str(), pmes + strlen(pmes))) {
226 sprintf(pmes+strlen(pmes),
"Is openmpi, mpich, intel-mpi, sgi-mpt etc. installed? If not in default location, need a LD_LIBRARY_PATH or MPI_LIB_NRN_PATH.\n");
231 sprintf(pmes+strlen(pmes),
"could not dynamically load libmpi.so or libmpich.so\n");
const char * dlerror(void)
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
int dlclose(void *handle)
char * getenv(const char *s)
void * dlopen(const char *path, int mode)
std::string corenrn_mpi_library
char * cxx_char_alloc(size_t sz)
#define error(err_num, fn_name)
void * dlsym(void *handle, const char *symbol)