TL; DR 如何在没有重建的情况下将ATLAS / MKL链接到现有的Numpy。
我使用Numpy用大矩阵计算,我发现它非常慢,因为Numpy只使用1个核心进行计算。经过大量的搜索,我发现我的Numpy没有链接到像ATLAS / MKL这样的优化库。这是我的numpy配置:
>>>import numpy as np
>>>np.__config__.show()
blas_info:
libraries = ['blas']
library_dirs = ['/usr/lib']
language = f77
lapack_info:
libraries = ['lapack']
library_dirs = ['/usr/lib']
language = f77
atlas_threads_info:
NOT AVAILABLE
blas_opt_info:
libraries = ['blas']
library_dirs = ['/usr/lib']
language = f77
define_macros = [('NO_ATLAS_INFO', 1)]
atlas_blas_threads_info:
NOT AVAILABLE
openblas_info:
NOT AVAILABLE
lapack_opt_info:
libraries = ['lapack', 'blas']
library_dirs = ['/usr/lib']
language = f77
define_macros = [('NO_ATLAS_INFO', 1)]
atlas_info:
NOT AVAILABLE
lapack_mkl_info:
NOT AVAILABLE
blas_mkl_info:
NOT AVAILABLE
atlas_blas_info:
NOT AVAILABLE
mkl_info:
NOT AVAILABLE
出于这个原因,我想将ATLAS / MKL链接到Numpy。但是,我的Numpy是从PIP安装的,因此我不想手动安装,因为我想使用最新版本。我做了一些搜索,但它们只是用于从头开始构建。出于这个原因,我的问题是:
答案 0 :(得分:25)
假设你正在运行某种版本的linux,这是你可以做到的一种方式:
使用ldd
找出当前链接的BLAS库numpy。
对于早于v1.10的numpy版本:
$ ldd /<path_to_site-packages>/numpy/core/_dotblas.so
例如,如果我通过apt-get
安装numpy,它会链接到
...
libblas.so.3 => /usr/lib/libblas.so.3 (0x00007fed81de8000)
...
如果_dotblas.so
不存在,这可能意味着numpy在最初安装时未能检测到任何BLAS库,在这种情况下它根本不构建任何BLAS库BLAS依赖的组件。如果使用pip
安装numpy而不手动指定BLAS库(见下文),则会发生这种情况。如果你想链接外部BLAS库,我恐怕你别无选择,只能重建numpy。
适用于numpy v1.10及更新版本:
来自numpy最新版本的 _dotblas.so
has been removed,但您应该能够检查multiarray.so
的依赖关系:
$ ldd /<path_to_site-packages>/numpy/core/multiarray.so
如果您还没有安装ATLAS / MKL / OpenBLAS。顺便说一句,我肯定会推荐OpenBLAS而不是ATLAS - 看看this answer(尽管基准测试数据现在可能有点过时了。)
使用update-alternatives
为您选择的新BLAS库创建符号链接。例如,如果您将libopenblas.so
安装到/opt/OpenBLAS/lib
,则可以执行以下操作:
$ sudo update-alternatives --install /usr/lib/libblas.so.3 \
libblas.so.3 \
/opt/OpenBLAS/lib/libopenblas.so \
50
您可以为单个目标库配置多个符号链接,允许您在多个已安装的BLAS库之间手动切换。
例如,当我调用$ sudo update-alternatives --config libblas.so.3
时,我可以选择3个库中的一个:
Selection Path Priority Status
------------------------------------------------------------
0 /opt/OpenBLAS/lib/libopenblas.so 40 auto mode
1 /opt/OpenBLAS/lib/libopenblas.so 40 manual mode
2 /usr/lib/atlas-base/atlas/libblas.so.3 35 manual mode
* 3 /usr/lib/libblas/libblas.so.3 10 manual mode
如果您真的想要numpy的“最新”版本,您还可以查看my answer on compiling numpy from source with OpenBLAS integration。
正如@tndoan在评论中提到的那样,通过在pip
中放置配置文件,可以使~/.numpy-site.cfg
尊重numpy的特定配置 - 有关详细信息,请参阅this answer。
我个人的偏好是手动配置和构建numpy。这并不是特别困难,它可以让你更好地控制numpy的配置。
答案 1 :(得分:1)
答案取决于最初如何构建NumPy。如果它是针对BLAS和LAPACK构建的,那么至少在没有重建的情况下,没有办法强制numpy.dot
以后使用ATLAS / MKL。其他功能不使用numpy.dot
,您可以使用update-alternatives
更改符号链接libblas.so.3
和liblapack.so.3
的目标。这是因为numpy.dot
需要ATLAS样式的CBLAS或OpenBLAS / MKL,而不是来自netlib的BLAS / CBLAS和LAPACK。
我正在使用openSUSE,我已经从netlib安装了标准的cblas-devel。然而,迫使NumPy使用运输的cblas / cblas-devel似乎是不可能的。也就是说,如果您针对netlib BLAS / LAPACK / CBLAS(作为官方软件包)构建了NumPy,则无法构建_dotblas.so
(提供numpy.dot
的BLAS版本)(或者在1.10之前),或{ {1}}(1.10及更高版本)根本不会链接到multiarray.so
。请参阅github上的问题:https://github.com/numpy/numpy/issues/1265和引用的Debian错误报告:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=464784。也许有人可以深入研究源代码来制作一个补丁...无论如何,它只是一个受影响的函数(libblas.so.3
),你现在可以使用更快的OpenBLAS轻松地重建整个NumPy,所以可能没什么大不了的毕竟是交易。
结论:您可以在不重建的情况下链接到ATLAS / MKL / OpenBLAS,但如果NumPy最初不是针对ATLAS / MKL / OpenBLAS构建的,那么numpy.dot
仍然会非常慢(因为numpy.dot
首先没有使用任何 BLAS,一旦编译完成,您就无法做任何事情。)
更新:实际上你可以强迫numpy构建numpy.dot
。我为numpy-1.9.2制作了一个补丁:
_dotblas.so
现在diff -Npru numpy-1.9.2.orig/numpy/core/setup.py numpy-1.9.2/numpy/core/setup.py
--- numpy-1.9.2.orig/numpy/core/setup.py 2015-02-01 11:38:25.000000000 -0500
+++ numpy-1.9.2/numpy/core/setup.py 2016-03-28 01:31:12.948885383 -0400
@@ -953,8 +953,8 @@ def configuration(parent_package='',top_
#blas_info = {}
def get_dotblas_sources(ext, build_dir):
if blas_info:
- if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []):
- return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient.
+ #if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []):
+ # return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient.
return ext.depends[:3]
return None # no extension module will be built
已与_dotblas.so
相关联,您可以使用libblas.so.3
来测试差异。