10
10
#define _GNU_SOURCE 1
11
11
#include <dlfcn.h>
12
12
#include <string.h>
13
+ #include <pthread.h>
13
14
#undef _GNU_SOURCE
14
15
#endif
15
16
@@ -29,30 +30,46 @@ static struct PyMethodDef methods[] = {
29
30
#define MKL_SERVICE_INLINE inline
30
31
#endif
31
32
32
- static MKL_SERVICE_INLINE void _set_mkl_ilp64 ();
33
- static MKL_SERVICE_INLINE void _set_mkl_lp64 ();
34
- static MKL_SERVICE_INLINE void _set_mkl_interface ();
33
+ static MKL_SERVICE_INLINE void _set_mkl_ilp64 (void );
34
+ static MKL_SERVICE_INLINE void _set_mkl_lp64 (void );
35
+ static MKL_SERVICE_INLINE void _set_mkl_interface (void );
36
+
37
+ static const char * mtlayer ;
38
+ static const char * verbose ;
35
39
36
- static void _preload_threading_layer () {
37
40
#if FORCE_PRELOADING
38
41
#define VERBOSE (...) if(verbose) printf("mkl-service + Intel(R) MKL: " __VA_ARGS__)
39
- #define SET_MTLAYER (L ) do { \
42
+ static void restore_mtlayer (void ) {
43
+ if (mtlayer ) {
44
+ VERBOSE ("Re-setting Intel(R) MKL_THREADING_LAYER=%s for the forked process\n" , mtlayer ); \
45
+ setenv ("MKL_THREADING_LAYER" , mtlayer , 1 );
46
+ } else {
47
+ VERBOSE ("Unsetting Intel(R) MKL_THREADING_LAYER variable for the forked process \n" ); \
48
+ unsetenv ("MKL_THREADING_LAYER" );
49
+ }
50
+ }
51
+ #endif
52
+
53
+ static void _preload_threading_layer (void ) {
54
+ #if FORCE_PRELOADING
55
+ #define SET_MTLAYER (L ) do { \
40
56
VERBOSE("setting Intel(R) MKL to use " #L " OpenMP runtime\n"); \
41
57
mkl_set_threading_layer(MKL_THREADING_##L); \
42
58
setenv("MKL_THREADING_LAYER", #L, 0); \
59
+ pthread_atfork(NULL, NULL, &restore_mtlayer); \
43
60
} while(0)
44
61
#define PRELOAD (lib ) do { \
45
62
VERBOSE("preloading %s runtime\n", lib); \
46
63
dlopen(lib, RTLD_LAZY|RTLD_GLOBAL); \
47
64
} while(0)
48
65
/*
49
66
* The following is the pseudo-code skeleton for reinterpreting unset MKL_THREADING_LAYER
50
- *
67
+ *
51
68
* if MKL_THREADING_LAYER is empty
52
69
* if kmp_calloc (or a suitable symbol identified by Terry) is loaded,
53
70
* we are using Intel(R) OpenMP, i.e. reinterpret as implicit value of INTEL
54
71
* otherwise check if other Open MP is loaded by checking get_omp_num_threads symbol
55
- * if not loaded:
72
+ * if not loaded:
56
73
* assume INTEL, and force loading of IOMP5
57
74
* if loaded:
58
75
* if Gnu OMP, set MKL_THREADING_LAYER=GNU, and call set_mkl_threading_layer(MKL_THREADING_GNU)
@@ -65,8 +82,14 @@ static void _preload_threading_layer() {
65
82
*/
66
83
67
84
const char * libiomp = "libiomp5.so" ;
68
- const char * verbose = getenv ("MKL_VERBOSE" );
69
- const char * mtlayer = getenv ("MKL_THREADING_LAYER" );
85
+ verbose = getenv ("MKL_VERBOSE" );
86
+ mtlayer = getenv ("MKL_THREADING_LAYER" );
87
+
88
+ /* Use of RTLD_DEFAULT handler is to indicate that symbol is being lookup-up among symbols
89
+ * presently known to this process.
90
+ *
91
+ * See: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html
92
+ */
70
93
void * omp = dlsym (RTLD_DEFAULT , "omp_get_num_threads" );
71
94
const char * omp_name = "(unidentified)" ;
72
95
const char * iomp = NULL ; /* non-zero indicates Intel(R) OpenMP is loaded */
@@ -108,21 +131,21 @@ static void _preload_threading_layer() {
108
131
return ;
109
132
}
110
133
111
- static MKL_SERVICE_INLINE void _set_mkl_ilp64 () {
134
+ static MKL_SERVICE_INLINE void _set_mkl_ilp64 (void ) {
112
135
#ifdef USING_MKL_RT
113
- int i = mkl_set_interface_layer (MKL_INTERFACE_ILP64 );
136
+ mkl_set_interface_layer (MKL_INTERFACE_ILP64 );
114
137
#endif
115
138
return ;
116
139
}
117
140
118
- static MKL_SERVICE_INLINE void _set_mkl_lp64 () {
141
+ static MKL_SERVICE_INLINE void _set_mkl_lp64 (void ) {
119
142
#ifdef USING_MKL_RT
120
- int i = mkl_set_interface_layer (MKL_INTERFACE_LP64 );
143
+ mkl_set_interface_layer (MKL_INTERFACE_LP64 );
121
144
#endif
122
145
return ;
123
146
}
124
147
125
- static MKL_SERVICE_INLINE void _set_mkl_interface () {
148
+ static MKL_SERVICE_INLINE void _set_mkl_interface (void ) {
126
149
_set_mkl_lp64 ();
127
150
_preload_threading_layer ();
128
151
}
0 commit comments