Python 使用OpenBLAS集成编译numpy

Python 使用OpenBLAS集成编译numpy,python,numpy,blas,atlas,openblas,Python,Numpy,Blas,Atlas,Openblas,我正在尝试使用OpenBLAS安装numpy,但是我不知道如何编写site.cfg文件 当安装完成后,没有出现错误,但是OpenBLAS使用的线程数从1增加(由环境变量OMP_NUM_threads控制)会导致性能下降 我不确定OpenBLAS集成是否完美。任何人都可以提供一个site.cfg文件来实现同样的功能 另外:OpenBLAS集成在其他工具包中,比如基于Python的工具包中,在同一台机器上增加线程数量时提供了显著的性能提升。我刚刚在virtualenv中编译了OpenBLAS集成,它

我正在尝试使用
OpenBLAS
安装
numpy
,但是我不知道如何编写
site.cfg
文件

当安装完成后,没有出现错误,但是OpenBLAS使用的线程数从1增加(由环境变量OMP_NUM_threads控制)会导致性能下降

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


另外:OpenBLAS集成在其他工具包中,比如基于Python的工具包中,在同一台机器上增加线程数量时提供了显著的性能提升。

我刚刚在
virtualenv
中编译了
OpenBLAS
集成,它似乎工作正常

这就是我的过程:

  • 编译OpenBLAS

    $ git clone https://github.com/xianyi/OpenBLAS
    $ cd OpenBLAS && make FC=gfortran
    $ sudo make PREFIX=/opt/OpenBLAS install
    
    如果您没有管理员权限,您可以将
    前缀=
    设置为您具有写入权限的目录(只需相应地修改下面的相应步骤)

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

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

      export LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
      
      启动新的终端会话时,
      LD\u LIBRARY\u PATH
      环境变量将被更新(使用
      $source~/.bashrc
      在同一会话中强制更新)

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

      $ sudo sh -c "echo '/opt/OpenBLAS/lib' > /etc/ld.so.conf.d/openblas.conf"
      
    完成任一选项后,运行

    $ sudo ldconfig
    
  • 抓取
    numpy
    源代码:

    $ git clone https://github.com/numpy/numpy
    $ cd numpy
    
  • site.cfg.example
    复制到
    site.cfg
    并编辑副本:

    $ cp site.cfg.example site.cfg
    $ nano site.cfg
    
    取消对这些行的注释:

    ....
    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    ....
    
  • 检查配置、构建和安装(可选在
    virtualenv
    中)

    输出应如下所示:

    ...
    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)]
    ...
    
    使用
    pip
    安装意味着使用
    python setup.py安装
    ,因为
    pip
    将跟踪软件包元数据,并允许您在将来轻松卸载或升级numpy

    $ pip install .
    
  • 可选:可用于测试不同线程数的性能

    $ 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
    

  • 对于更高的线程数,性能似乎有了明显的改善。然而,我还没有系统地对此进行测试,对于较小的矩阵,额外的开销可能会超过线程数增加带来的性能好处。

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

    sudo apt-get install numpy libopenblas-dev
    
    在一个全新的docker ubuntu上,我测试了从博客文章复制的以下脚本

    如果没有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
    
    在我用
    apt install openblas dev
    安装openblas之后,我检查了与的numpy链接

    import numpy as np
    np.__config__.show()
    
    信息是

    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
    
    它不显示与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
    

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

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

    $ brew install gcc
    
  • 从源代码[或使用包管理器]编译
    OpenBLAS
    ,获取源代码repo或:

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

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

  • 创建一个
    ~/.numpy site.cfg
    文件,其中包含步骤2中使用的前缀路径:

    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    runtime_library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    
    include_dirs
    用于编译器<代码>库目录
    用于链接器
    runtime\u library\u dirs
    用于加载程序,可能不需要

  • pip从源代码安装numpy和scipy(最好安装到virtualenv中),而无需手动下载[您也可以指定发布版本]:

    pip install numpy scipy --no-binary numpy,scipy
    
  • 根据我的经验,运行时的
    OPENBLAS\u NUM\u THREADS
    设置使OPENBLAS更快,而不是更慢,尤其是当多个CPU进程同时使用它时:

     export OPENBLAS_NUM_THREADS=1
    
    (或者,您可以使用
    make FC=gfortran USE\u THREAD=0
    编译OpenBLAS)


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

    当您说性能下降时,您确定问题严重到足以保证额外的线程吗?对于太小的问题,使用额外线程时会导致性能下降,我不知道openblas是否足够聪明,只在有用时使用额外线程。为了检查性能随问题大小的变化,我尝试在随机生成的各种大小的矩阵上使用numpy.linalg.svd函数,(100x100、100x1000、1000x1000、1000x100010000x1000)但在所有这些情况下,使用openblas中的单线程可以实现最佳执行时间。即使计算量很大(例如10000x1000矩阵SVD)单线程需要5000秒,而3个线程需要6000秒。这让我有点担心,我只想检查openblas集成是否正确。我应用了你所做的,但在测试脚本/linalg/lapack_lite中出现了愚蠢的错误。所以:未定义的符号:zgelsd_我有以下行,即使我严格按照你键入的答案来做。libopenblas.so.0=>/usr/lib/libopenblas.so.0(0x00007f77e08fc000)还有一个问题。openBlas依赖于OpenPI还是使用它可以提高性能?2015年,我对这里建议的步骤有一些问题。我发现效果更好。@Afshin-如果不是
    sudo
    用户,最好改变第一步
    sudo make PREFIX=/opt/openBlas install[openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    runtime_library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    
    pip install numpy scipy --no-binary numpy,scipy
    
     export OPENBLAS_NUM_THREADS=1