web-dev-qa-db-ja.com

ATLAS / MKLをインストール済みのNumpyにリンクする

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からインストールされるため、最新バージョンを使用したいので手動でインストールしたくありません。私はいくつかの検索を行いましたが、それらはゼロから構築するためのものです。このため、私の質問は次のとおりです。

  • 再構築せずにATLAS/MKLをNumpyにリンクする方法はありますか?
  • 設定情報がNumpyのインストール済みフォルダーの_config_。pyに保存されていることを発見しました。それを変更することで私の問題は解決しますか?はいの場合、どのように見せていただけますか?
22
tndoan

ある種のLinuxを実行していると仮定すると、次の方法で実行できます。

  1. 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ライブラリとリンクしたい場合は、numpyを再構築するしかありません。


  2. ATLAS/MKL/OpenBLASをまだインストールしていない場合はインストールします。ちなみに、私はATLASよりもOpenBLASをお勧めします- この答え を見てください(ただし、ベンチマークデータはおそらく少し古くなっています)。

  3. 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の「最新」バージョンが本当に必要な場合は、 OpenBLAS統合を使用してソースからnumpyをコンパイルすることについての私の答え も参照してください。

ピップを使用してBLASサポート付きのnumpyをインストールする

コメントで@tndoanが述べたように、~/.numpy-site.cfgに構成ファイルを配置することで、pipにnumpyの特定の構成を尊重させることができます。詳細については、 この回答 を参照してください。

私の個人的な好みは、手作業でnumpyを設定してビルドすることです。これは特に難しいことではありません。numpyの構成をよりよく制御できます。

26
ali_m

答えは、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.sonumpy.dotのBLASバージョンを提供する)はビルドできません(1.10より前)、またはmultiarray.so(1.10以降)はlibblas.so.3にまったくリンクしていません。 githubの問題を参照してください: https://github.com/numpy/numpy/issues/1265 および引用されているDebianバグレポート: https://bugs.debian.org/cgi -bin/bugreport.cgi?bug = 464784 。たぶん誰かがソースコードに飛び込んでパッチを作ることができます...とにかく、影響を受けるのは1つの関数(numpy.dot)だけであり、高速のOpenBLASを使用してNumPy全体をいつでも簡単に再構築できるので、おそらくそれほど大きくありません結局対処します。

結論:後で再構築せずにATLAS/MKL/OpenBLASにリンクできますが、NumPyが構築されていない場合、numpy.dotは依然として非常に遅くなります最初はATLAS/MKL/OpenBLAS(numpy.dotanyBLASを使用していないため、最初は何もできません)コンパイルが行われました)。

更新:実際には、numpyに_dotblas.soをビルドさせることができます。 numpy-1.9.2のパッチを作成しました。

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.solibblas.so.3にリンクされたので、update-alternativesを使用して違いをテストできます。

1
Molec