Ссылка 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. Так решит ли это изменение моей проблемы? Если да, не могли бы вы показать мне, как?
2 ответа
Предполагая, что вы работаете с Linux, вы можете сделать это одним из способов:
Узнайте, с какой библиотекой BLAS в настоящее время связана numpy
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 и новее:
_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
Я могу выбрать одну из 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.
Ответ зависит от того, как изначально был построен NumPy. Если он был построен против BLAS и LAPACK, то, по крайней мере, нет никакого способа заставить numpy.dot
использовать ATLAS/MKL позже без перестройки. Другие функции не используют numpy.dot
и вы можете использовать update-alternatives
изменить цели символических ссылок libblas.so.3
а также liblapack.so.3
, Это потому что numpy.dot
требуется CBLAS в стиле ATLAS или 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
чтобы проверить разницу.