1 #if !defined(PETSC4PY_COMPAT_MPI_H)
2 #define PETSC4PY_COMPAT_MPI_H
3
4 #if defined(OPEN_MPI)
5
6 /*
7 * The hackery below redefines the actual calls to 'MPI_Init()' and
8 * 'MPI_Init_thread()' in order to preload the main MPI dynamic
9 * library with appropriate flags to 'dlopen()' ensuring global
10 * availability of library symbols.
11 */
12
13 #if !defined(OPENMPI_DLOPEN_LIBMPI) && defined(OMPI_MAJOR_VERSION)
14 #if OMPI_MAJOR_VERSION >= 3 && OMPI_MAJOR_VERSION < 10
15 #define OPENMPI_DLOPEN_LIBMPI 0
16 #endif
17 #endif
18
19 #if !defined(OPENMPI_DLOPEN_LIBMPI)
20 #define OPENMPI_DLOPEN_LIBMPI 1
21 #endif
22
23 #if OPENMPI_DLOPEN_LIBMPI
24 #if HAVE_DLOPEN
25
26 #if HAVE_DLFCN_H
27 #include <dlfcn.h>
28 #else
29 #if defined(__linux__)
30 #define RTLD_LAZY 0x00001
31 #define RTLD_NOW 0x00002
32 #define RTLD_LOCAL 0x00000
33 #define RTLD_GLOBAL 0x00100
34 #define RTLD_NOLOAD 0x00004
35 #define RTLD_NODELETE 0x01000
36 #define RTLD_DEEPBIND 0x00008
37 #elif defined(__APPLE__)
38 #define RTLD_LAZY 0x1
39 #define RTLD_NOW 0x2
40 #define RTLD_LOCAL 0x4
41 #define RTLD_GLOBAL 0x8
42 #define RTLD_NOLOAD 0x10
43 #define RTLD_NODELETE 0x80
44 #define RTLD_FIRST 0x100
45 #elif defined(__CYGWIN__)
46 #define RTLD_LAZY 1
47 #define RTLD_NOW 2
48 #define RTLD_LOCAL 0
49 #define RTLD_GLOBAL 4
50 #endif
51 #if defined(__cplusplus) || defined(c_plusplus)
52 extern "C" {
53 #endif
54 extern void *dlopen(const char *, int);
55 extern void *dlsym(void *, const char *);
56 extern int dlclose(void *);
57 extern char *dlerror(void);
58 #if defined(__cplusplus) || defined(c_plusplus)
59 }
60 #endif
61 #endif
62
63 #if !defined(RTLD_LAZY)
64 #define RTLD_LAZY 1
65 #endif
66 #if !defined(RTLD_NOW)
67 #define RTLD_NOW RTLD_LAZY
68 #endif
69 #if !defined(RTLD_LOCAL)
70 #define RTLD_LOCAL 0
71 #endif
72 #if !defined(RTLD_GLOBAL)
73 #define RTLD_GLOBAL RTLD_LOCAL
74 #endif
75
76 /*
77 static void * my_dlopen(const char *name, int mode) {
78 void *handle;
79 static int called = 0;
80 if (!called) {
81 called = 1;
82 #if HAVE_DLFCN_H
83 printf("HAVE_DLFCN_H: yes\n");
84 #else
85 printf("HAVE_DLFCN_H: no\n");
86 #endif
87 printf("\n");
88 printf("RTLD_LAZY: 0x%X\n", RTLD_LAZY);
89 printf("RTLD_NOW: 0x%X\n", RTLD_NOW);
90 printf("RTLD_LOCAL: 0x%X\n", RTLD_LOCAL);
91 printf("RTLD_GLOBAL: 0x%X\n", RTLD_GLOBAL);
92 #ifdef RTLD_NOLOAD
93 printf("RTLD_NOLOAD: 0x%X\n", RTLD_NOLOAD);
94 #endif
95 printf("\n");
96 }
97 handle = dlopen(name, mode);
98 printf("dlopen(\"%s\",0x%X) -> %p\n", name, mode, handle);
99 printf("dlerror() -> %s\n\n", dlerror());
100 return handle;
101 }
102 #define dlopen my_dlopen
103 */
104
OPENMPI_dlopen_libmpi(void)105 static void OPENMPI_dlopen_libmpi(void)
106 {
107 void *handle = 0;
108 int mode = RTLD_NOW | RTLD_GLOBAL;
109 #if defined(__APPLE__)
110 /* macOS */
111 #ifdef RTLD_NOLOAD
112 mode |= RTLD_NOLOAD;
113 #endif
114 #if defined(OMPI_MAJOR_VERSION)
115 #if OMPI_MAJOR_VERSION == 3
116 if (!handle) handle = dlopen("libmpi.40.dylib", mode);
117 #elif OMPI_MAJOR_VERSION == 2
118 if (!handle) handle = dlopen("libmpi.20.dylib", mode);
119 #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 10
120 if (!handle) handle = dlopen("libmpi.12.dylib", mode);
121 #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 6
122 if (!handle) handle = dlopen("libmpi.1.dylib", mode);
123 #elif OMPI_MAJOR_VERSION == 1
124 if (!handle) handle = dlopen("libmpi.0.dylib", mode);
125 #endif
126 #endif
127 if (!handle) handle = dlopen("libmpi.dylib", mode);
128 #else
129 /* GNU/Linux and others */
130 #ifdef RTLD_NOLOAD
131 mode |= RTLD_NOLOAD;
132 #endif
133 #if defined(OMPI_MAJOR_VERSION)
134 #if OMPI_MAJOR_VERSION >= 10 /* IBM Spectrum MPI */
135 if (!handle) handle = dlopen("libmpi_ibm.so.2", mode);
136 if (!handle) handle = dlopen("libmpi_ibm.so.1", mode);
137 if (!handle) handle = dlopen("libmpi_ibm.so", mode);
138 #elif OMPI_MAJOR_VERSION == 3
139 if (!handle) handle = dlopen("libmpi.so.40", mode);
140 #elif OMPI_MAJOR_VERSION == 2
141 if (!handle) handle = dlopen("libmpi.so.20", mode);
142 #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 10
143 if (!handle) handle = dlopen("libmpi.so.12", mode);
144 #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 6
145 if (!handle) handle = dlopen("libmpi.so.1", mode);
146 #elif OMPI_MAJOR_VERSION == 1
147 if (!handle) handle = dlopen("libmpi.so.0", mode);
148 #endif
149 #endif
150 if (!handle) handle = dlopen("libmpi.so", mode);
151 #endif
152 }
153
PetscInitialize_OpenMPI(int * argc,char *** args,const char file[],const char help[])154 static PetscErrorCode PetscInitialize_OpenMPI(int *argc,char ***args,
155 const char file[],
156 const char help[])
157 {
158 OPENMPI_dlopen_libmpi();
159 return PetscInitialize(argc,args,file,help);
160 }
161 #undef PetscInitialize
162 #define PetscInitialize PetscInitialize_OpenMPI
163
164 #endif /* HAVE_DLOPEN */
165 #endif /* OPENMPI_DLOPEN_LIBMPI */
166
167 #endif /* OPEN_MPI */
168
169 #endif/*PETSC4PY_COMPAT_MPI_H*/
170