Подтвердить что ты не робот

Свяжите 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 без повторной настройки?
  • Я обнаружил, что информация о конфигурации сохраняется в _config_.py в установленной папке Numpy. Так изменит ли он его решение? Если да, не могли бы вы показать мне, как?
4b9b3361

Ответ 1

Предполагая, что вы используете какой-то вкус linux, здесь один из способов сделать это:

  • Узнайте, что в настоящее время связано с numpy библиотеки BLAS с использованием ldd.

    • Для версий numpy старше v1.10:

      $ ldd /<path_to_site-packages>/numpy/core/_dotblas.so
      

      Например, если я устанавливаю numpy через apt-get, он ссылается на

      ...
      libblas.so.3 => /usr/lib/libblas.so.3 (0x00007fed81de8000)
      ...
      

      Если _dotblas.so не существует, это, вероятно, означает, что numpy не удалось обнаружить библиотеки BLAS, когда они были изначально установлены, и в этом случае он просто не создает какой-либо из BLAS- зависимых компонентов. Это часто происходит, если вы устанавливаете numpy с помощью pip, не указывая вручную BLAS-библиотеку (см. Ниже). Боюсь, у вас не будет выбора, кроме как восстановить numpy, если вы хотите связать себя с внешней библиотекой BLAS.


    • Для numpy v1.10 и new:

      _dotblas.so был удален из последних версий numpy, но вы должны иметь возможность проверить зависимостей multiarray.so:

      $ ldd /<path_to_site-packages>/numpy/core/multiarray.so
      
  • Установите ATLAS/MKL/OpenBLAS, если вы еще этого не сделали. Кстати, я определенно рекомендую OpenBLAS над ATLAS - посмотрите этот ответ (хотя данные бенчмаркинга теперь, вероятно, немного устарели).

  • Используйте 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, я могу выбрать одну из трех библиотек:

      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, вы можете также взглянуть на мой ответ на компиляцию numpy из источника с интеграцией OpenBLAS.

Установка numpy с поддержкой BLAS с помощью pip

Как упоминалось в комментариях @tndoan, можно сделать pip для конкретной конфигурации для numpy, поместив файл конфигурации в ~/.numpy-site.cfg - см. этот ответ для более подробной информации.

Мои личные предпочтения - настраивать и строить numpy вручную. Это не особенно сложно, и это дает вам лучший контроль над конфигурацией numpy.

Ответ 2

Ответ зависит от того, как NumPy был построен изначально. Если он был создан против BLAS и LAPACK, то, по крайней мере, нет способа заставить numpy.dot использовать ATLAS/MKL позже без перестройки. Другие функции не используют numpy.dot, и вы можете использовать update-alternatives для изменения целей символических ссылок libblas.so.3 и liblapack.so.3. Это связано с тем, что numpy.dot требует ATLAS в стиле CBLAS или OpenBLAS/MKL, но не BLAS/CBLAS и LAPACK из netlib.

Я использую openSUSE, и я установил стандартный cblas-devel из netlib. Однако, кажется, просто невозможно заставить NumPy использовать отправленный cblas/cblas-devel. То есть, если вы создали NumPy против netlib BLAS/LAPACK/CBLAS (как официальный пакет), то _dotblas.so (который предоставляет версию BLAS numpy.dot) не может быть построен (до 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. Может быть, кто-то может погрузиться в исходный код, чтобы сделать патч... Во всяком случае, это всего лишь одна функция, которая затронута (numpy.dot), и вы всегда можете легко перестроить весь NumPy с помощью более быстрого OpenBLAS, так что, вероятно, все.

Вывод: Вы можете перейти на ATLAS/MKL/OpenBLAS позже без перестройки, но numpy.dot будет по-прежнему очень медленным, если NumPy не был построен ранее с ATLAS/MKL/OpenBLAS (потому что numpy.dot просто не использовал любой BLAS в первую очередь, и вы ничего не можете сделать об этом после завершения компиляции).

Обновление: На самом деле вы можете заставить 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.so связан с libblas.so.3, вы можете использовать update-alternatives для проверки разницы.