使用OpenBLAS集成编译numpy

Vij*_*jay 50 python numpy blas atlas

我试图安装numpyOpenBLAS,但我在损失的如何site.cfg文件需要被写入.

在遵循安装过程时,安装完成且没有错误,但是将OpenBLAS使用的线程数从1增加(由环境变量OMP_NUM_THREADS控制)会导致性能下降.

我不确定OpenBLAS集成是否完美.任何人都可以提供一个site.cfg文件来实现相同的目标.

PS:OpenBLAS集成在其他工具包中,比如基于Python的Theano,可以在同一台机器上增加线程数量,从而大幅提升性能.

ali*_*i_m 92

我只是编numpyvirtualenvOpenBLAS整合,它似乎是工作确定.

这是我的过程:

  1. 编译OpenBLAS:

    $ git clone https://github.com/xianyi/OpenBLAS
    $ cd OpenBLAS && make FC=gfortran
    $ sudo make PREFIX=/opt/OpenBLAS install
    
    Run Code Online (Sandbox Code Playgroud)

    如果您没有管理员权限,则可以设置PREFIX=为具有写权限的目录(只需相应地修改下面的相应步骤).

  2. 确保包含的目录libopenblas.so位于共享库搜索路径中.

    • 要在本地执行此操作,您可以编辑~/.bashrc文件以包含该行

      export LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
      
      Run Code Online (Sandbox Code Playgroud)

      LD_LIBRARY_PATH当你开始一个新的终端会话(使用环境变量将被更新$ source ~/.bashrc,迫使同一个会话中更新).

    • 另一个适用于多个用户的选项是创建一个包含该行的.conf文件,例如:/etc/ld.so.conf.d//opt/OpenBLAS/lib

      $ sudo sh -c "echo '/opt/OpenBLAS/lib' > /etc/ld.so.conf.d/openblas.conf"
      
      Run Code Online (Sandbox Code Playgroud)

    完成任一选项后,运行

    $ sudo ldconfig
    
    Run Code Online (Sandbox Code Playgroud)
  3. 抓取numpy源代码:

    $ git clone https://github.com/numpy/numpy
    $ cd numpy
    
    Run Code Online (Sandbox Code Playgroud)
  4. 复制site.cfg.examplesite.cfg和编辑副本:

    $ cp site.cfg.example site.cfg
    $ nano site.cfg
    
    Run Code Online (Sandbox Code Playgroud)

    取消注释这些行:

    ....
    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    ....
    
    Run Code Online (Sandbox Code Playgroud)
  5. 检查配置,构建,安装(可选内部virtualenv)

    $ python setup.py config
    
    Run Code Online (Sandbox Code Playgroud)

    输出应该如下所示:

    ...
    openblas_info:
      FOUND:
        libraries = ['openblas', 'openblas']
        library_dirs = ['/opt/OpenBLAS/lib']
        language = c
        define_macros = [('HAVE_CBLAS', None)]
    
      FOUND:
        libraries = ['openblas', 'openblas']
        library_dirs = ['/opt/OpenBLAS/lib']
        language = c
        define_macros = [('HAVE_CBLAS', None)]
    ...
    
    Run Code Online (Sandbox Code Playgroud)

    与安装pip最好python setup.py install的,因为pip将跟踪包的元数据,让你轻松卸载或将来升级numpy的.

    $ pip install .
    
    Run Code Online (Sandbox Code Playgroud)
  6. 可选:您可以使用此脚本测试不同线程计数的性能.

    $ OMP_NUM_THREADS=1 python build/test_numpy.py
    
    version: 1.10.0.dev0+8e026a2
    maxint:  9223372036854775807
    
    BLAS info:
     * libraries ['openblas', 'openblas']
     * library_dirs ['/opt/OpenBLAS/lib']
     * define_macros [('HAVE_CBLAS', None)]
     * language c
    
    dot: 0.099796795845 sec
    
    $ OMP_NUM_THREADS=8 python build/test_numpy.py
    
    version: 1.10.0.dev0+8e026a2
    maxint:  9223372036854775807
    
    BLAS info:
     * libraries ['openblas', 'openblas']
     * library_dirs ['/opt/OpenBLAS/lib']
     * define_macros [('HAVE_CBLAS', None)]
     * language c
    
    dot: 0.0439578056335 sec
    
    Run Code Online (Sandbox Code Playgroud)

对于更高的线程数,性能似乎有明显的改善.但是,我没有对此进行过系统的测试,对于较小的矩阵,额外的开销可能会超过更高线程数的性能优势.

  • 我在你的测试脚本/linalg/lapack_lite.so上应用了你所做的以及错误的错误:未定义的符号:zgelsd_ (4认同)
  • @Afshin - 如果不是`sudo`用户,最好改变第一步`sudo make PREFIX =/opt/OpenBLAS install`来使用你自己主目录中一个位置的前缀(例如`make PREFIX =/home/your_username/my_software /`),然后应该允许您为自己的文件运行`ldconfig`命令. (2认同)

ent*_*ron 6

如果您使用的是ubuntu或mint,您可以通过apt-get安装numpy和openblas,轻松实现openblas链接numpy

sudo apt-get install numpy libopenblas-dev
Run Code Online (Sandbox Code Playgroud)

在一个新鲜的docker ubuntu上,我测试了从博客文章"安装Numpy和OpenBLAS"复制的以下脚本

import numpy as np
import numpy.random as npr
import time

# --- Test 1
N = 1
n = 1000

A = npr.randn(n,n)
B = npr.randn(n,n)

t = time.time()
for i in range(N):
    C = np.dot(A, B)
td = time.time() - t
print("dotted two (%d,%d) matrices in %0.1f ms" % (n, n, 1e3*td/N))

# --- Test 2
N = 100
n = 4000

A = npr.randn(n)
B = npr.randn(n)

t = time.time()
for i in range(N):
    C = np.dot(A, B)
td = time.time() - t
print("dotted two (%d) vectors in %0.2f us" % (n, 1e6*td/N))

# --- Test 3
m,n = (2000,1000)

A = npr.randn(m,n)

t = time.time()
[U,s,V] = np.linalg.svd(A, full_matrices=False)
td = time.time() - t
print("SVD of (%d,%d) matrix in %0.3f s" % (m, n, td))

# --- Test 4
n = 1500
A = npr.randn(n,n)

t = time.time()
w, v = np.linalg.eig(A)
td = time.time() - t
print("Eigendecomp of (%d,%d) matrix in %0.3f s" % (n, n, td))
Run Code Online (Sandbox Code Playgroud)

没有openblas,结果是:

dotted two (1000,1000) matrices in 563.8 ms
dotted two (4000) vectors in 5.16 us
SVD of (2000,1000) matrix in 6.084 s
Eigendecomp of (1500,1500) matrix in 14.605 s
Run Code Online (Sandbox Code Playgroud)

安装openblas后apt install openblas-dev,我检查了numpy链接

import numpy as np
np.__config__.show()
Run Code Online (Sandbox Code Playgroud)

而信息是

atlas_threads_info:
  NOT AVAILABLE
openblas_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
atlas_3_10_threads_info:
  NOT AVAILABLE
blas_info:
    library_dirs = ['/usr/lib']
    libraries = ['blas', 'blas']
    language = c
    define_macros = [('HAVE_CBLAS', None)]
mkl_info:
  NOT AVAILABLE
atlas_3_10_blas_threads_info:
  NOT AVAILABLE
atlas_3_10_blas_info:
  NOT AVAILABLE
openblas_lapack_info:
  NOT AVAILABLE
lapack_opt_info:
    library_dirs = ['/usr/lib']
    libraries = ['lapack', 'lapack', 'blas', 'blas']
    language = c
    define_macros = [('NO_ATLAS_INFO', 1), ('HAVE_CBLAS', None)]
blas_opt_info:
    library_dirs = ['/usr/lib']
    libraries = ['blas', 'blas']
    language = c
    define_macros = [('NO_ATLAS_INFO', 1), ('HAVE_CBLAS', None)]
atlas_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
atlas_3_10_info:
  NOT AVAILABLE
lapack_info:
    library_dirs = ['/usr/lib']
    libraries = ['lapack', 'lapack']
    language = f77
atlas_blas_threads_info:
  NOT AVAILABLE
Run Code Online (Sandbox Code Playgroud)

它没有显示与openblas的联系.但是,脚本的新结果显示numpy必须使用openblas:

dotted two (1000,1000) matrices in 15.2 ms
dotted two (4000) vectors in 2.64 us
SVD of (2000,1000) matrix in 0.469 s
Eigendecomp of (1500,1500) matrix in 2.794 s
Run Code Online (Sandbox Code Playgroud)


Jer*_*101 5

这是一个比 @ali_m 的答案更简单的方法,它适用于 macOS。

  1. 如果没有 gfortran 编译器,请安装一个。例如在 macOS 上使用自制软件:

    $ brew install gcc
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从源代码编译OpenBLAS[或使用包管理器],获取源代码库或下载版本

    $ git clone https://github.com/xianyi/OpenBLAS
    $ cd OpenBLAS && make FC=gfortran
    $ sudo make PREFIX=/opt/OpenBLAS install
    
    Run Code Online (Sandbox Code Playgroud)

    如果您不会/不能 sudo,请设置PREFIX=到另一个目录并在下一步中修改路径。

    OpenBLAS 不需要位于编译器包含路径或链接器库路径上。

  3. 创建一个~/.numpy-site.cfg包含您在步骤 2 中使用的 PREFIX 路径的文件:

    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    runtime_library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    
    Run Code Online (Sandbox Code Playgroud)

    include_dirs是给编译器用的。library_dirs用于链接器。runtime_library_dirs用于加载程序,可能不需要。

  4. 从源代码(最好是到 virtualenv 中)pip-install numpy 和 scipy,无需手动下载它们[您也可以指定发行版本]:

    pip install numpy scipy --no-binary numpy,scipy
    
    Run Code Online (Sandbox Code Playgroud)
  5. 根据我的经验,OPENBLAS_NUM_THREADS运行时的此设置使 OpenBLAS 更快,而不是更慢,尤其是。当多个CPU进程同时使用它时:

     export OPENBLAS_NUM_THREADS=1
    
    Run Code Online (Sandbox Code Playgroud)

    (或者,您可以使用 编译 OpenBLAS make FC=gfortran USE_THREAD=0。)

有关测试方法,请参阅其他答案。