[LINUX] MKL taints symbol table (PLT / procedure linkage table)

Introduction

Related to https://qiita.com/cielavenir/items/93d2b5b057bfe1383670.

Suppose you have A.so and B.so, A is statically linked to libmkl_rt and B is statically linked to libblas. At this time, if A.so and B.so are dynamically linked [^ 1], A should use libmkl_rt and B should use libblas for BLAS implementation. However, in reality, if A calls the BLAS function of MKL and then loads B, B will also use MKL for the BLAS implementation. This can be a problem if (unlikely) B depends on the behavior of BLAS implementations other than MKL [^ 2]. However, there seems to be no workaround this time ...

demo

The binary package for scipy / spatial / qhull.so links to libopenblas, but running the following in the LD_DEBUG = "libs symbols" environment can load the MKL dgetrf / dgetrs / dgecon (instead of libopenblas) Be observed. Note that ʻimport scipy` does not load scipy / spatial / qhull.so.

#!/usr/bin/python
import numpy
import scipy  # this does not guarantee scipy.spatial safety.
print(numpy.dot([[1,2]],[[3],[4]]))
points = numpy.random.rand(30, 2)  # 30 random points in 2-D

import ctypes
n=ctypes.c_int(3)
alpha=ctypes.c_double(3)
beta=ctypes.c_double(-2)
A=(ctypes.c_double*9)(1,2,9,8,10,-5,3,8,-1)
B=(ctypes.c_double*9)(9,3,-8,8,11,6,3,2.3,1)
C=(ctypes.c_double*9)(3,8,6,3,4,1,1.2,8,-2)
# this CDLL loads so using RTLD_LOCAL
ctypes.CDLL("libmkl_rt.so").cblas_dgemm(102,111,111,n,n,n,alpha,A,n,B,n,beta,C,n)
print(list(C))

print '=== check dgetrf/dgetrs/dgecon below ==='
from scipy.spatial import ConvexHull
hull = ConvexHull(points)

in conclusion

There was something I thought about, and when I added a pattern that uses multiple modules in the previous demo, I was able to reproduce it (because it uses the constructor attribute), it can be reproduced just by loading it without calling a function). Isn't libmkl_rt just doing that dlopen reopen to observe the behavior ...?

Recommended Posts

MKL taints symbol table (PLT / procedure linkage table)