Intel10_64lp(等)でビルドされたshared objectをRTLD_LOCALでロードすると、「Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.」となって落ちます。
静的リンクまたはRTLD_GLOBALでロードすれば問題ありません。
しかし、Pythonモジュールのロードはsys.setdlopenflagsでグローバルに書き換えないといけないので、実用的には厳しいと思われます。
BLA_VENDOR=Intel10_64lp(等)は、CMake 3.13以降で自動的に優先されます。
CMake 3.17ではBLA_VENDOR=Intel10_64_dynが使えます(これを使えば解決します)が、明示的に指定しなければなりません。優先順位の変更はしないという返信を受けているので、shared objectに対してfind_package(BLAS)するときは自分で気をつけるしかなさそうです。
demo: https://github.com/cielavenir/cmake_intel_blas
[C] load blas user statically
ans=[ [ 2.10e+01, 3.36e+02, 7.08e+01]; [ -6.40e+01, 5.14e+02, 9.50e+01]; [ 2.10e+02, 3.10e+01, 4.75e+01] ]
[C] load lapack user dynamically
ans=[ [ 2.10e+01, 3.36e+02, 7.08e+01]; [ -6.40e+01, 5.14e+02, 9.50e+01]; [ 2.10e+02, 3.10e+01, 4.75e+01] ]
[Python] load blas user [cdll]
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
[Python] load blas user [cdll] with modifying dlopenflags
ans=[ [ 2.10e+01, 3.36e+02, 7.08e+01]; [ -6.40e+01, 5.14e+02, 9.50e+01]; [ 2.10e+02, 3.10e+01, 4.75e+01] ]
[Python] load blas user [module]
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
[Python] load blas user [module] with modifying dlopenflags
ans=[ [ 2.10e+01, 3.36e+02, 7.08e+01]; [ -6.40e+01, 5.14e+02, 9.50e+01]; [ 2.10e+02, 3.10e+01, 4.75e+01] ]
まああれです、openraveです。あっちはfind_package(LAPACK)ですが、同様の事象を抱えています。
200820
以下のコード片をfunc.cppに挿入することで問題を回避することができました。
#include <dlfcn.h>
__attribute__((constructor)) static void fixcmakemkl(){
dlopen("libmkl_intel_lp64.so",RTLD_LAZY|RTLD_NOLOAD|RTLD_GLOBAL);
dlopen("libmkl_intel_thread.so",RTLD_LAZY|RTLD_NOLOAD|RTLD_GLOBAL);
dlopen("libmkl_core.so",RTLD_LAZY|RTLD_NOLOAD|RTLD_GLOBAL);
}
libdlについていろいろ調査している最中にRTLD_NOLOADを発見しました。libdlは奥が深い(まあランタイムなんてみんなそうか)。