How is mkl bundled with PyTorch in pypi wheels?

david-macleod: <p>Running <code>torch.backends.mkl.is_available()</code> against pypi installed versions of PyTorch returns <code>True</code>. However I cannot see where the mkl runtime is (.so files) are actually contained within the wheel, could someone let me know how PyTorch bundles mkl into its pip installable wheels?</p>

ashari4: <p>Yes, I observed this as well with <code>torch 1.9.1</code>.</p>
<p>Running <code>print(torch.__config__.parallel_info())</code> seems to indicate that MKL is enabled.</p>
<pre><code class="lang-auto">ATen/Parallel:
        at::get_num_threads() : 4
        at::get_num_interop_threads() : 4
OpenMP 201511 (a.k.a. OpenMP 4.5)
        omp_get_max_threads() : 4
Intel(R) Math Kernel Library Version 2020.0.0 Product Build 20191122 for Intel(R) 64 architecture applications
        mkl_get_max_threads() : 4
Intel(R) MKL-DNN v2.1.2 (Git Hash 98be7e8afa711dc9b66c8ff3504129cb82013cdb)
std::thread::hardware_concurrency() : 8
Environment variables:
        OMP_NUM_THREADS : [not set]
        MKL_NUM_THREADS : [not set]
ATen parallel backend: OpenMP
</code></pre>
<p>However, if I run <code>ldd libtorch_python.so | grep "libmkl*"</code>, I get no matches.</p>

ptrblck: <p><code>ldd</code> prints shared libraries, while MKL is statically linked, if I’m not mistaken, so use <code>nm -gDC</code>.</p>

ashari4: <p>Thanks. <code>nm -gDC libtorch_python.so | grep mkl</code> results in only <code>mkl-dnn</code> symbols being found.</p>
<pre><code class="lang-auto">0000000000a33d80 T THPVariable_is_mkldnn(THPVariable*, void*)
                 U at::_baddbmm_mkl_(at::Tensor&amp;, at::Tensor const&amp;, at::Tensor const&amp;, c10::Scalar const&amp;, c10::Scalar const&amp;)
                 U at::mkldnn_linear(at::Tensor const&amp;, at::Tensor const&amp;, c10::optional&lt;at::Tensor&gt; const&amp;)
                 U at::_mkldnn_reshape(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;)
                 U at::_mkldnn_transpose(at::Tensor const&amp;, long, long)
                 U at::mkldnn_max_pool2d(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, bool)
                 U at::mkldnn_max_pool3d(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, bool)
                 U at::_mkldnn_transpose_(at::Tensor&amp;, long, long)
                 U at::mkldnn_convolution(at::Tensor const&amp;, at::Tensor const&amp;, c10::optional&lt;at::Tensor&gt; const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, long)
                 U at::mkldnn_adaptive_avg_pool2d(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;)
                 U at::mkldnn_reorder_conv2d_weight(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, long)
                 U at::mkldnn_reorder_conv3d_weight(at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, long)
                 U at::mkldnn_linear_backward_weights(at::Tensor const&amp;, at::Tensor const&amp;, at::Tensor const&amp;, bool)
                 U at::mkldnn_convolution_backward_weights(c10::ArrayRef&lt;long&gt;, at::Tensor const&amp;, at::Tensor const&amp;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, c10::ArrayRef&lt;long&gt;, long, bool)
                 U at::Tensor::to_mkldnn(c10::optional&lt;c10::ScalarType&gt;) const
</code></pre>
<p>Do you know where the static linking of MKL happens?</p>