web-dev-qa-db-fra.com

Compiler numpy avec l'intégration OpenBLAS

J'essaie d'installer numpy avec OpenBLAS, mais je ne sais pas comment le fichier site.cfg doit être écrit. 

Lorsque la procédure d'installation } a été suivie, l'installation s'est terminée sans erreur. Toutefois, l'augmentation du nombre de threads utilisés par OpenBLAS à partir de 1 a entraîné une dégradation des performances.

Je ne sais pas si l'intégration OpenBLAS a été parfaite. Quelqu'un pourrait-il fournir un fichier site.cfg pour obtenir le même résultat?.

P.S .: L’intégration d’OpenBLAS dans d’autres boîtes à outils telles que Theano , basée sur Python, améliore considérablement les performances en augmentant le nombre de threads sur la même machine.

46
Vijay

Je viens de compiler numpy dans une virtualenv avec une intégration OpenBLAS et cela semble fonctionner correctement.

C'était mon processus:

  1. Compiler OpenBLAS:

    $ git clone https://github.com/xianyi/OpenBLAS
    $ cd OpenBLAS && make FC=gfortran
    $ Sudo make PREFIX=/opt/OpenBLAS install
    

    Si vous ne possédez pas de droits d'administrateur, vous pouvez définir PREFIX= dans un répertoire où vous disposez des privilèges d'écriture (modifiez simplement les étapes correspondantes ci-dessous en conséquence).

  2. Assurez-vous que le répertoire contenant libopenblas.so se trouve dans le chemin de recherche de votre bibliothèque partagée.

    • Pour faire cela localement, vous pouvez éditer votre fichier ~/.bashrc pour qu'il contienne la ligne

      export LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
      

      La variable d'environnement LD_LIBRARY_PATH sera mise à jour lorsque vous démarrez une nouvelle session de terminal (utilisez $ source ~/.bashrc pour forcer une mise à jour dans la même session).

    • Une autre option qui fonctionnera pour plusieurs utilisateurs consiste à créer un fichier .conf dans /etc/ld.so.conf.d/ contenant la ligne /opt/OpenBLAS/lib, par exemple:

      $ Sudo sh -c "echo '/opt/OpenBLAS/lib' > /etc/ld.so.conf.d/openblas.conf"
      

    Une fois que vous avez terminé avec l'une ou l'autre option, exécutez

    $ Sudo ldconfig
    
  3. Prenez le code source numpy:

    $ git clone https://github.com/numpy/numpy
    $ cd numpy
    
  4. Copiez site.cfg.example dans site.cfg et éditez la copie:

    $ cp site.cfg.example site.cfg
    $ nano site.cfg
    

    Décommentez ces lignes:

    ....
    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    ....
    
  5. Vérifier la configuration, construire, installer (éventuellement dans une virtualenv)

    $ python setup.py config
    

    La sortie devrait ressembler à ceci:

    ...
    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)]
    ...
    

    L'installation avec pip est préférable à utiliser python setup.py install, car pip gardera une trace des métadonnées du paquet et vous permettra de désinstaller ou de mettre à jour numpy facilement à l'avenir.

    $ pip install .
    
  6. Facultatif: vous pouvez utiliser ce script pour tester les performances pour différents nombres de threads.

    $ 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
    

Il semble y avoir une amélioration notable des performances pour un nombre de threads plus élevé. Cependant, je n'ai pas testé cela de manière très systématique, et il est probable que pour les matrices plus petites, les frais généraux supplémentaires l'emporteraient sur les avantages en termes de performances d'un nombre de threads plus élevé.

85
ali_m

Juste au cas où vous utiliseriez Ubuntu ou menthe, vous pouvez facilement avoir openblas lié numpy en installant numpy et openblas via apt-get as

Sudo apt-get install numpy libopenblas-dev

Sur un nouveau menu fixe Ubuntu, j’ai testé le script suivant, copié à partir de la publication de blog "Installation de Numpy et 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))

Sans openblas, le résultat est:

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

Après avoir installé openblas avec apt install openblas-dev, j’ai vérifié le lien numpy avec 

import numpy as np
np.__config__.show()

et l'information est

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

Cela ne montre pas le lien avec les openblas. Cependant, le nouveau résultat du script indique que numpy doit avoir utilisé 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
6
entron

Voici une approche plus simple que celle de @ ALi_m et cela fonctionne sur macOS.

  1. Installez un compilateur gfortran si vous n'en avez pas. Par exemple. Utilisation de l'homebrew sur macOS:

    $ brew install gcc
    
  2. Compilez OpenBLAS à partir du source [l'installation d'une version devrait également fonctionner sauf si vous avez besoin de correctifs de bogues non publiés]:

    $ git clone https://github.com/xianyi/OpenBLAS
    $ cd OpenBLAS && make FC=gfortran
    $ Sudo make PREFIX=/opt/OpenBLAS install
    

    Si vous ne pouvez pas/ne pouvez pas utiliser Sudo, définissez PREFIX= dans un autre répertoire et modifiez le chemin à l'étape suivante.

    OpenBLAS n'a pas besoin d'être sur le chemin d'accès du compilateur ni sur le chemin de la bibliothèque de l'éditeur de liens.

  3. Télécharger https://github.com/numpy/numpy/blob/master/site.cfg.example to ~/.numpy-site.cfg, décommentez ces lignes et modifiez-les pour donner le chemin PREFIX que vous avez utilisé à l'étape 2:

    [openblas]
    libraries = openblas
    library_dirs = /opt/OpenBLAS/lib
    include_dirs = /opt/OpenBLAS/include
    
  4. pip-install numpy et scipy depuis les sources (de préférence dans un virtualenv) sans les télécharger manuellement [vous pouvez également spécifier les versions des versions]:

    pip install numpy scipy --no-binary numpy,scipy
    

Voir les autres réponses pour savoir comment le tester.

0
Jerry101