Skip to content

Commit 084e70c

Browse files
authored
Attempt to resolve the TLS problem (#25390) (#25469)
* attempt to resolve tls problem, test=develop * add glibc version check, test=develop * fix regex, test=develop * refine get_libc_ver, test=develop * refine get_libc_ver, test=develop
1 parent 6bf75c1 commit 084e70c

File tree

2 files changed

+68
-19
lines changed

2 files changed

+68
-19
lines changed

cmake/external/mkldnn.cmake

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,12 @@ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${MKLDNN_INSTALL_DIR}/${LIBDIR
3636

3737
INCLUDE_DIRECTORIES(${MKLDNN_INC_DIR}) # For MKLDNN code to include internal headers.
3838

39-
IF(${CBLAS_PROVIDER} STREQUAL "MKLML")
40-
SET(MKLDNN_DEPENDS ${MKLML_PROJECT})
41-
MESSAGE(STATUS "Build MKLDNN with MKLML ${MKLML_ROOT}")
42-
ELSE()
43-
MESSAGE(STATUS "Build MKLDNN without MKLML")
44-
ENDIF()
4539

4640
IF(NOT WIN32)
4741
SET(MKLDNN_FLAG "-Wno-error=strict-overflow -Wno-error=unused-result -Wno-error=array-bounds")
4842
SET(MKLDNN_FLAG "${MKLDNN_FLAG} -Wno-unused-result -Wno-unused-value")
4943
SET(MKLDNN_CFLAG "${CMAKE_C_FLAGS} ${MKLDNN_FLAG}")
5044
SET(MKLDNN_CXXFLAG "${CMAKE_CXX_FLAGS} ${MKLDNN_FLAG}")
51-
52-
IF(${CBLAS_PROVIDER} STREQUAL "MKLML")
53-
# Force libmkldnn.so to link libiomp5.so (provided by intel mkl) instead of libgomp.so (provided by gcc),
54-
# since core_avx.so links libiomp5.so
55-
set(MKLDNN_SHARED_LINKER_FLAG "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-as-needed -L${MKLML_LIB_DIR} -liomp5")
56-
set(FORBID "-fopenmp")
57-
ELSE()
58-
set(MKLDNN_SHARED_LINKER_FLAG "${CMAKE_SHARED_LINKER_FLAGS}")
59-
set(FORBID "")
60-
ENDIF()
6145
ELSE()
6246
SET(MKLDNN_CXXFLAG "${CMAKE_CXX_FLAGS} /EHsc")
6347
ENDIF(NOT WIN32)
@@ -91,8 +75,6 @@ ExternalProject_Add(
9175
-DCMAKE_C_FLAGS=${MKLDNN_CFLAG}
9276
-DCMAKE_CXX_FLAGS=${MKLDNN_CXXFLAG}
9377
-DDNNL_BUILD_TESTS=OFF -DDNNL_BUILD_EXAMPLES=OFF
94-
-DCMAKE_SHARED_LINKER_FLAGS=${MKLDNN_SHARED_LINKER_FLAG}
95-
-DCMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS=${FORBID}
9678
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${MKLDNN_INSTALL_DIR}
9779
)
9880
if(WIN32)

python/paddle/fluid/core.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import site
1818
import sys
1919
import os
20+
import warnings
21+
import platform
2022

2123
core_suffix = 'so'
2224
if os.name == 'nt':
@@ -62,7 +64,6 @@ def avx_supported():
6264
"""
6365
Whether current system(Linux, MacOS, Windows) is supported with AVX.
6466
"""
65-
import platform
6667
from .. import compat as cpt
6768
sysstr = platform.system().lower()
6869
has_avx = False
@@ -160,6 +161,72 @@ def asm_func(code_str, restype=ctypes.c_uint32, argtypes=()):
160161
return False
161162

162163

164+
def run_shell_command(cmd):
165+
import subprocess
166+
out, err = subprocess.Popen(
167+
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
168+
shell=True).communicate()
169+
if err:
170+
return None
171+
else:
172+
return out.decode('utf-8')
173+
174+
175+
def get_dso_path(core_so, dso_name):
176+
if core_so and dso_name:
177+
return run_shell_command("ldd %s|grep %s|awk '{print $3}'" %
178+
(core_so, dso_name)).strip()
179+
else:
180+
return None
181+
182+
183+
def load_dso(dso_absolute_path):
184+
if dso_absolute_path:
185+
try:
186+
from ctypes import cdll
187+
cdll.LoadLibrary(dso_absolute_path)
188+
except:
189+
warnings.warn("Load {} failed".format(dso_absolute_path))
190+
191+
192+
def pre_load(dso_name):
193+
if has_avx_core:
194+
core_so = current_path + os.sep + 'core_avx.' + core_suffix
195+
elif has_noavx_core:
196+
core_so = current_path + os.sep + 'core_noavx.' + core_suffix
197+
else:
198+
core_so = None
199+
dso_path = get_dso_path(core_so, dso_name)
200+
load_dso(dso_path)
201+
202+
203+
def get_glibc_ver():
204+
return run_shell_command("ldd --version | awk '/ldd/{print $NF}'").strip()
205+
206+
207+
def less_than_ver(a, b):
208+
import re
209+
import operator
210+
211+
def to_list(s):
212+
s = re.sub('(\.0+)+$', '', s)
213+
return [int(x) for x in s.split('.')]
214+
215+
return operator.lt(to_list(a), to_list(b))
216+
217+
218+
# NOTE(zhiqiu): An error may occurs when import paddle in linux platform with glibc < 2.22,
219+
# the error message of which is "dlopen: cannot load any more object with static TLS".
220+
# This happens when:
221+
# (1) the number of dynamic shared librarys (DSO) loaded > 14,
222+
# (2) after that, load a dynamic shared library (DSO) with static TLS.
223+
# For paddle, the problem is that 'libgomp' is a DSO with static TLS, and it is loaded after 14 DSOs.
224+
# So, here is a tricky way to solve the problem by pre load 'libgomp' before 'core_avx.so'.
225+
# The final solution is to upgrade glibc to > 2.22 on the target system.
226+
if platform.system().lower() == 'linux' and less_than_ver(get_glibc_ver(),
227+
'2.23'):
228+
pre_load('libgomp')
229+
163230
load_noavx = False
164231

165232
if avx_supported():

0 commit comments

Comments
 (0)