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 ...
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]],[,])) 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)
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 ...?