xref: /petsc/src/binding/petsc4py/src/lib-petsc/compat/mpi.h (revision 9d47de495d3c23378050c1b4a410c12a375cb6c6)
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