Skip to content

Commit 729b1f6

Browse files
Fixed issue/14
1. Use `pthread_atfork` to restore MKL threading layer environment variable set by init code for the forked process. 2. Fixed multiple GCC compiler warnings.
1 parent a712dd3 commit 729b1f6

File tree

1 file changed

+37
-14
lines changed

1 file changed

+37
-14
lines changed

mkl/_mklinitmodule.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _GNU_SOURCE 1
1111
#include <dlfcn.h>
1212
#include <string.h>
13+
#include <pthread.h>
1314
#undef _GNU_SOURCE
1415
#endif
1516

@@ -29,30 +30,46 @@ static struct PyMethodDef methods[] = {
2930
#define MKL_SERVICE_INLINE inline
3031
#endif
3132

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;
3539

36-
static void _preload_threading_layer() {
3740
#if FORCE_PRELOADING
3841
#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 { \
4056
VERBOSE("setting Intel(R) MKL to use " #L " OpenMP runtime\n"); \
4157
mkl_set_threading_layer(MKL_THREADING_##L); \
4258
setenv("MKL_THREADING_LAYER", #L, 0); \
59+
pthread_atfork(NULL, NULL, &restore_mtlayer); \
4360
} while(0)
4461
#define PRELOAD(lib) do { \
4562
VERBOSE("preloading %s runtime\n", lib); \
4663
dlopen(lib, RTLD_LAZY|RTLD_GLOBAL); \
4764
} while(0)
4865
/*
4966
* The following is the pseudo-code skeleton for reinterpreting unset MKL_THREADING_LAYER
50-
*
67+
*
5168
* if MKL_THREADING_LAYER is empty
5269
* if kmp_calloc (or a suitable symbol identified by Terry) is loaded,
5370
* we are using Intel(R) OpenMP, i.e. reinterpret as implicit value of INTEL
5471
* otherwise check if other Open MP is loaded by checking get_omp_num_threads symbol
55-
* if not loaded:
72+
* if not loaded:
5673
* assume INTEL, and force loading of IOMP5
5774
* if loaded:
5875
* 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() {
6582
*/
6683

6784
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+
*/
7093
void *omp = dlsym(RTLD_DEFAULT, "omp_get_num_threads");
7194
const char *omp_name = "(unidentified)";
7295
const char *iomp = NULL; /* non-zero indicates Intel(R) OpenMP is loaded */
@@ -108,21 +131,21 @@ static void _preload_threading_layer() {
108131
return;
109132
}
110133

111-
static MKL_SERVICE_INLINE void _set_mkl_ilp64() {
134+
static MKL_SERVICE_INLINE void _set_mkl_ilp64(void) {
112135
#ifdef USING_MKL_RT
113-
int i = mkl_set_interface_layer(MKL_INTERFACE_ILP64);
136+
mkl_set_interface_layer(MKL_INTERFACE_ILP64);
114137
#endif
115138
return;
116139
}
117140

118-
static MKL_SERVICE_INLINE void _set_mkl_lp64() {
141+
static MKL_SERVICE_INLINE void _set_mkl_lp64(void) {
119142
#ifdef USING_MKL_RT
120-
int i = mkl_set_interface_layer(MKL_INTERFACE_LP64);
143+
mkl_set_interface_layer(MKL_INTERFACE_LP64);
121144
#endif
122145
return;
123146
}
124147

125-
static MKL_SERVICE_INLINE void _set_mkl_interface() {
148+
static MKL_SERVICE_INLINE void _set_mkl_interface(void) {
126149
_set_mkl_lp64();
127150
_preload_threading_layer();
128151
}

0 commit comments

Comments
 (0)