77
88#if (defined(USING_MKL_RT ) && defined(__linux__ ))
99#define FORCE_PRELOADING 1
10- #define _GNU_SOURCE 1
10+ #define _GNU_SOURCE 1
1111#include <dlfcn.h>
1212#include <pthread.h>
1313#include <string.h>
@@ -37,130 +37,143 @@ static const char *verbose;
3737
3838#if FORCE_PRELOADING
3939#define VERBOSE (...) \
40- if (verbose) \
41- printf("mkl-service + Intel(R) MKL: " __VA_ARGS__)
42-
43- static void restore_mtlayer (void ) {
44- if (mtlayer ) {
45- VERBOSE (
46- "Re-setting Intel(R) MKL_THREADING_LAYER=%s for the forked process\n" ,
47- mtlayer );
48- setenv ("MKL_THREADING_LAYER" , mtlayer , 1 );
49- } else {
50- VERBOSE ("Unsetting Intel(R) MKL_THREADING_LAYER variable for the forked "
40+ if (verbose) \
41+ printf("mkl-service + Intel(R) MKL: " __VA_ARGS__)
42+
43+ static void restore_mtlayer (void )
44+ {
45+ if (mtlayer ) {
46+ VERBOSE ("Re-setting Intel(R) MKL_THREADING_LAYER=%s for the forked "
47+ "process\n" ,
48+ mtlayer );
49+ setenv ("MKL_THREADING_LAYER" , mtlayer , 1 );
50+ }
51+ else {
52+ VERBOSE (
53+ "Unsetting Intel(R) MKL_THREADING_LAYER variable for the forked "
5154 "process \n" );
52- unsetenv ("MKL_THREADING_LAYER" );
53- }
55+ unsetenv ("MKL_THREADING_LAYER" );
56+ }
5457}
5558#endif
5659
57- static void _preload_threading_layer (void ) {
60+ static void _preload_threading_layer (void )
61+ {
5862#if FORCE_PRELOADING
5963#define SET_MTLAYER (L ) \
60- do { \
61- VERBOSE("setting Intel(R) MKL to use " #L " OpenMP runtime\n"); \
62- mkl_set_threading_layer(MKL_THREADING_##L); \
63- setenv("MKL_THREADING_LAYER", #L, 0); \
64- pthread_atfork(NULL, NULL, &restore_mtlayer); \
65- } while (0)
64+ do { \
65+ VERBOSE("setting Intel(R) MKL to use " #L " OpenMP runtime\n"); \
66+ mkl_set_threading_layer(MKL_THREADING_##L); \
67+ setenv("MKL_THREADING_LAYER", #L, 0); \
68+ pthread_atfork(NULL, NULL, &restore_mtlayer); \
69+ } while (0)
6670#define PRELOAD (lib ) \
67- do { \
68- VERBOSE("preloading %s runtime\n", lib); \
69- dlopen(lib, RTLD_LAZY | RTLD_GLOBAL); \
70- } while (0)
71- /*
72- * The following is the pseudo-code skeleton for reinterpreting unset
73- * MKL_THREADING_LAYER
74- *
75- * if MKL_THREADING_LAYER is empty
76- * if kmp_calloc (or a suitable symbol identified by Terry) is
77- * loaded, we are using Intel(R) OpenMP, i.e. reinterpret as implicit value of
78- * INTEL otherwise check if other Open MP is loaded by checking
79- * get_omp_num_threads symbol if not loaded: assume INTEL, and force loading
80- * of IOMP5 if loaded: if Gnu OMP, set MKL_THREADING_LAYER=GNU, and call
81- * set_mkl_threading_layer(MKL_THREADING_GNU) if other vendors? if
82- * MKL_THREADING_LAYER is INTEL force loading of iomp, to preempt possibility
83- * of other modules loading other OMP library before MKL is actually used
84- *
85- * should we treat other possible values of MKL_THREADING_LAYER
86- * specially?
87- *
88- */
89-
90- const char * libiomp = "libiomp5.so" ;
91- verbose = getenv ("MKL_VERBOSE" );
92- mtlayer = getenv ("MKL_THREADING_LAYER" );
93-
94- /* Use of RTLD_DEFAULT handler is to indicate that symbol is being lookup-up
95- * among symbols presently known to this process.
96- *
97- * See: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html
98- */
99- void * omp = dlsym (RTLD_DEFAULT , "omp_get_num_threads" );
100- const char * omp_name = "(unidentified)" ;
101- const char * iomp = NULL ; /* non-zero indicates Intel(R) OpenMP is loaded */
102- Dl_info omp_info ;
103-
104- if (verbose && (verbose [0 ] == 0 || atoi (verbose ) == 0 ))
105- verbose = NULL ;
106-
107- VERBOSE ("THREADING LAYER: %s\n" , mtlayer );
108-
109- if (omp ) {
110- if (dladdr (omp , & omp_info )) {
111- omp_name = basename (
112- omp_info .dli_fname ); /* GNU version doesn't modify argument */
113- iomp = strstr (omp_name , libiomp );
71+ do { \
72+ VERBOSE("preloading %s runtime\n", lib); \
73+ dlopen(lib, RTLD_LAZY | RTLD_GLOBAL); \
74+ } while (0)
75+ /*
76+ * The following is the pseudo-code skeleton for reinterpreting unset
77+ * MKL_THREADING_LAYER
78+ *
79+ * if MKL_THREADING_LAYER is empty
80+ * if kmp_calloc (or a suitable symbol identified by Terry) is
81+ * loaded, we are using Intel(R) OpenMP, i.e. reinterpret as implicit value
82+ * of INTEL otherwise check if other Open MP is loaded by checking
83+ * get_omp_num_threads symbol if not loaded: assume INTEL, and force loading
84+ * of IOMP5 if loaded: if Gnu OMP, set MKL_THREADING_LAYER=GNU, and call
85+ * set_mkl_threading_layer(MKL_THREADING_GNU) if other vendors? if
86+ * MKL_THREADING_LAYER is INTEL force loading of iomp, to preempt
87+ * possibility of other modules loading other OMP library before MKL is
88+ * actually used
89+ *
90+ * should we treat other possible values of MKL_THREADING_LAYER
91+ * specially?
92+ *
93+ */
94+
95+ const char * libiomp = "libiomp5.so" ;
96+ verbose = getenv ("MKL_VERBOSE" );
97+ mtlayer = getenv ("MKL_THREADING_LAYER" );
98+
99+ /* Use of RTLD_DEFAULT handler is to indicate that symbol is being lookup-up
100+ * among symbols presently known to this process.
101+ *
102+ * See:
103+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html
104+ */
105+ void * omp = dlsym (RTLD_DEFAULT , "omp_get_num_threads" );
106+ const char * omp_name = "(unidentified)" ;
107+ const char * iomp = NULL ; /* non-zero indicates Intel(R) OpenMP is loaded */
108+ Dl_info omp_info ;
109+
110+ if (verbose && (verbose [0 ] == 0 || atoi (verbose ) == 0 ))
111+ verbose = NULL ;
112+
113+ VERBOSE ("THREADING LAYER: %s\n" , mtlayer );
114+
115+ if (omp ) {
116+ if (dladdr (omp , & omp_info )) {
117+ omp_name = basename (
118+ omp_info .dli_fname ); /* GNU version doesn't modify argument */
119+ iomp = strstr (omp_name , libiomp );
120+ }
121+ VERBOSE ("%s OpenMP runtime %s is already loaded\n" ,
122+ iomp ? "Intel(R)" : "Other vendor" , omp_name );
114123 }
115- VERBOSE ("%s OpenMP runtime %s is already loaded\n" ,
116- iomp ? "Intel(R)" : "Other vendor" , omp_name );
117- }
118- if (!mtlayer || mtlayer [0 ] == 0 ) { /* unset or empty */
119- if (omp ) { /* if OpenMP runtime is loaded */
120- if (iomp ) /* if Intel runtime is loaded */
121- SET_MTLAYER (INTEL );
122- else /* otherwise, assume it is GNU OpenMP */
123- SET_MTLAYER (GNU );
124- } else { /* nothing is loaded */
125- SET_MTLAYER (INTEL );
126- PRELOAD (libiomp );
124+ if (!mtlayer || mtlayer [0 ] == 0 ) { /* unset or empty */
125+ if (omp ) { /* if OpenMP runtime is loaded */
126+ if (iomp ) /* if Intel runtime is loaded */
127+ SET_MTLAYER (INTEL );
128+ else /* otherwise, assume it is GNU OpenMP */
129+ SET_MTLAYER (GNU );
130+ }
131+ else { /* nothing is loaded */
132+ SET_MTLAYER (INTEL );
133+ PRELOAD (libiomp );
134+ }
127135 }
128- } else if (strcasecmp (mtlayer , "intel" ) ==
136+ else if (strcasecmp (mtlayer , "intel" ) ==
129137 0 ) { /* Intel runtime is requested */
130- if (omp && !iomp ) {
131- fprintf (stderr ,
132- "Error: mkl-service + Intel(R) MKL: MKL_THREADING_LAYER=INTEL is "
133- "incompatible with %s library."
134- "\n\tTry to import numpy first or set the threading layer "
135- "accordingly. "
136- "Set MKL_SERVICE_FORCE_INTEL to force it.\n" ,
137- omp_name );
138- if (!getenv ("MKL_SERVICE_FORCE_INTEL" ))
139- exit (1 );
140- } else
141- PRELOAD (libiomp );
142- }
138+ if (omp && !iomp ) {
139+ fprintf (stderr ,
140+ "Error: mkl-service + Intel(R) MKL: "
141+ "MKL_THREADING_LAYER=INTEL is "
142+ "incompatible with %s library."
143+ "\n\tTry to import numpy first or set the threading layer "
144+ "accordingly. "
145+ "Set MKL_SERVICE_FORCE_INTEL to force it.\n" ,
146+ omp_name );
147+ if (!getenv ("MKL_SERVICE_FORCE_INTEL" ))
148+ exit (1 );
149+ }
150+ else
151+ PRELOAD (libiomp );
152+ }
143153#endif
144- return ;
154+ return ;
145155}
146156
147- static MKL_SERVICE_INLINE void _set_mkl_ilp64 (void ) {
157+ static MKL_SERVICE_INLINE void _set_mkl_ilp64 (void )
158+ {
148159#ifdef USING_MKL_RT
149- mkl_set_interface_layer (MKL_INTERFACE_ILP64 );
160+ mkl_set_interface_layer (MKL_INTERFACE_ILP64 );
150161#endif
151- return ;
162+ return ;
152163}
153164
154- static MKL_SERVICE_INLINE void _set_mkl_lp64 (void ) {
165+ static MKL_SERVICE_INLINE void _set_mkl_lp64 (void )
166+ {
155167#ifdef USING_MKL_RT
156- mkl_set_interface_layer (MKL_INTERFACE_LP64 );
168+ mkl_set_interface_layer (MKL_INTERFACE_LP64 );
157169#endif
158- return ;
170+ return ;
159171}
160172
161- static MKL_SERVICE_INLINE void _set_mkl_interface (void ) {
162- _set_mkl_lp64 ();
163- _preload_threading_layer ();
173+ static MKL_SERVICE_INLINE void _set_mkl_interface (void )
174+ {
175+ _set_mkl_lp64 ();
176+ _preload_threading_layer ();
164177}
165178
166179#if defined(IS_PY3K )
@@ -177,20 +190,22 @@ static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT,
177190
178191/* Initialization function for the module */
179192#if defined(IS_PY3K )
180- PyMODINIT_FUNC PyInit__mklinit (void ) {
181- PyObject * m ;
182-
183- _set_mkl_interface ();
184- m = PyModule_Create (& moduledef );
185- if (!m ) {
186- return NULL ;
187- }
193+ PyMODINIT_FUNC PyInit__mklinit (void )
194+ {
195+ PyObject * m ;
196+
197+ _set_mkl_interface ();
198+ m = PyModule_Create (& moduledef );
199+ if (!m ) {
200+ return NULL ;
201+ }
188202
189- return m ;
203+ return m ;
190204}
191205#else
192- PyMODINIT_FUNC init_mklinit (void ) {
193- _set_mkl_interface ();
194- Py_InitModule ("_mklinit" , methods );
206+ PyMODINIT_FUNC init_mklinit (void )
207+ {
208+ _set_mkl_interface ();
209+ Py_InitModule ("_mklinit" , methods );
195210}
196211#endif
0 commit comments