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

Python: Как вы останавливаете numpy от многопоточности?

Я знаю, что это может показаться смешным вопросом, но я должен регулярно запускать задания на вычислительных серверах, которые я разделяю с другими в отделе, и когда я запускаю 10 заданий, мне действительно хотелось бы, чтобы он просто взял 10 сердечники и не более; Меня не волнует, если это займет немного больше времени с одним ядром за ход: я просто не хочу, чтобы он вторгался на территорию других, что потребовало бы, чтобы я поменял рабочие места и так далее. Я просто хочу иметь 10 твердых ядер и все.

В частности, я использую Enthought 7.3-1 на Redhat, основанный на Python 2.7.3 и numpy 1.6.1, но вопрос более общий. Я искал какой-то ответ на этот вопрос в течение нескольких часов безрезультатно, поэтому, если кто-то знает о переключателе в numpy, который может отключить многопоточность, сообщите мне.

4b9b3361

Ответ 1

Установите переменную среды MKL_NUM_THREADS равную 1. Как вы могли догадаться, эта переменная среды управляет поведением библиотеки математического ядра, которая включена в состав Enthought numpy build.

Я просто делаю это в моем файле запуска,.bash_profile, с export MKL_NUM_THREADS=1. Вы также должны быть в состоянии сделать это изнутри вашего script, чтобы он был специфичным для процесса.

Ответ 2

Только, надеюсь, это исправляет все сценарии и систему, в которых вы можете быть.

  1. Используйте 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)