Компиляция NumPy с интеграцией OpenBLAS
Я пытаюсь установить numpy
с OpenBLAS
Однако я в растерянности относительно того, как site.cfg
файл должен быть написан.
При выполнении процедуры установки установка завершилась без ошибок, однако наблюдается снижение производительности при увеличении числа потоков, используемых OpenBLAS, с 1 (управляется переменной среды OMP_NUM_THREADS).
Я не уверен, была ли интеграция OpenBLAS идеальной. Может ли кто-нибудь предоставить site.cfg
файл для достижения того же.
PS: интеграция OpenBLAS с другими наборами инструментов, такими как Theano, основанная на Python, обеспечивает существенное повышение производительности при увеличении количества потоков на одной машине.
2 ответа
Я только что скомпилировал numpy
внутри virtualenv
с OpenBLAS
интеграция, и, кажется, работает нормально.
Это был мой процесс:
компилировать
OpenBLAS
:$ git clone https://github.com/xianyi/OpenBLAS $ cd OpenBLAS && make FC=gfortran $ sudo make PREFIX=/opt/OpenBLAS install
Если у вас нет прав администратора, вы можете установить
PREFIX=
в каталог, в котором у вас есть права на запись (просто измените соответствующие шаги ниже).Убедитесь, что каталог, содержащий
libopenblas.so
находится в вашей общей папке поиска в библиотеке.Чтобы сделать это локально, вы можете отредактировать
~/.bashrc
файл, содержащий строкуexport LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
LD_LIBRARY_PATH
Переменная окружения будет обновлена при запуске нового сеанса терминала (используйте$ source ~/.bashrc
заставить обновление в течение того же сеанса).Другим вариантом, который будет работать для нескольких пользователей, является создание
.conf
файл в/etc/ld.so.conf.d/
содержащий строку/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
)$ python setup.py config
Вывод должен выглядеть примерно так:
... 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 install
, поскольку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, вы можете легко связать NumPy с OpenBlas, установив NUMPY и OpenBLAS через apt-get as
sudo apt-get install numpy libopenblas-dev
На свежем доке Ubuntu я протестировал следующий скрипт, скопированный из поста блога "Установка Numpy и 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))
Без 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
После того, как я установил openblas с apt install openblas-dev
Я проверил 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
из исходного кода [установка релиза также должна работать, если вам не нужны неопубликованные исправления ошибок]:$ git clone https://github.com/xianyi/OpenBLAS $ cd OpenBLAS && make FC=gfortran $ sudo make PREFIX=/opt/OpenBLAS install
Если вы не можете / не можете судо, установите
PREFIX=
в другой каталог и измените путь на следующем шаге.OpenBLAS не обязательно должен указывать путь компилятора или путь к библиотеке компоновщика.
Загрузите https://github.com/numpy/numpy/blob/master/site.cfg.example для
~/.numpy-site.cfg
, раскомментируйте эти строки и отредактируйте их, указав путь PREFIX, который вы использовали в шаге 2:[openblas] libraries = openblas library_dirs = /opt/OpenBLAS/lib include_dirs = /opt/OpenBLAS/include
pip-install numpy и scipy из исходного кода (желательно в virtualenv), не загружая их вручную [вы также можете указать версии выпуска]:
pip install numpy scipy --no-binary numpy,scipy
Посмотрите другие ответы для способов проверить это.