Python: Как вы останавливаете numpy от многопоточности?
Я знаю, что это может показаться смешным вопросом, но я должен регулярно запускать задания на вычислительных серверах, которые я разделяю с другими в отделе, и когда я запускаю 10 заданий, мне действительно хотелось бы, чтобы он просто взял 10 сердечники и не более; Меня не волнует, если это займет немного больше времени с одним ядром за ход: я просто не хочу, чтобы он вторгался на территорию других, что потребовало бы, чтобы я поменял рабочие места и так далее. Я просто хочу иметь 10 твердых ядер и все.
В частности, я использую Enthought 7.3-1 на Redhat, основанный на Python 2.7.3 и numpy 1.6.1, но вопрос более общий. Я искал какой-то ответ на этот вопрос в течение нескольких часов безрезультатно, поэтому, если кто-то знает о переключателе в numpy, который может отключить многопоточность, сообщите мне.
Ответы
Ответ 1
Установите переменную среды MKL_NUM_THREADS
равную 1. Как вы могли догадаться, эта переменная среды управляет поведением библиотеки математического ядра, которая включена в состав Enthought numpy
build.
Я просто делаю это в моем файле запуска,.bash_profile, с export MKL_NUM_THREADS=1
. Вы также должны быть в состоянии сделать это изнутри вашего script, чтобы он был специфичным для процесса.
Ответ 2
Только, надеюсь, это исправляет все сценарии и систему, в которых вы можете быть.
- Используйте
numpy.__config__.show()
чтобы узнать, используете ли вы OpenBLAS или MKL
С этого момента вы можете сделать это несколькими способами.
2.1. Терминальный маршрут export OPENBLAS_NUM_THREADS=1
или export MKL_NUM_THREADS=1
2.2 (Это мой предпочтительный способ). В скрипте python import os
и добавьте строку os.environ['OPENBLAS_NUM_THREADS'] = '1'
или os.environ['MKL_NUM_THREADS'] = '1'
.
ПРИМЕЧАНИЕ при установке os.environ[VAR]
количество потоков должно быть строкой! Кроме того, вам может потребоваться установить эту переменную среды перед импортом numpy/scipy.
Есть, вероятно, другие варианты, помимо openBLAS или MKL, но шаг 1 поможет вам понять это.
Ответ 3
Если вы хотите установить число потоков динамически, а не глобально через переменную окружения, вы также можете сделать:
import mkl
mkl.set_num_threads(2)
Ответ 4
Я бы оставил это в качестве комментария к ответу Би Рико, но у меня нет необходимой привилегии. В более поздних версиях numpy я нашел необходимым также установить NUMEXPR_NUM_THREADS = 1
В моих руках это достаточно, если не установить MKL_NUM_THREADS = 1, но при некоторых обстоятельствах вам может потребоваться установить оба.
Ответ 5
Для меня решение было простым, так как я прекратил использовать numpy.dot
:
import numpy as np
a = np.random.rand(1e6)
b = np.random.rand(1e6, 10)
# potentially uses multiple threads
dotted = np.dot(a, b)
# single-thread
summed = np.sum(a[:, np.newaxis] * b, axis=0)
assert np.all(dotted == summed)