Странный многопроцессорный блок, импортирующий функцию Numba
Окружающая среда
- GNU/Linux (Fedora 25).
- среда Conda.
- Python 3.6.1.
- Numba 0.33.0 (np112py36_0).
Начальная настройка (отлично работает)
Два файла main.py
и numbamodule.py
:
main.py
Что порождает 2 процесса для запуска функции execute_numba
.
import time
from importlib import import_module
from multiprocessing import Process
def execute_numba(name):
# Import the function
importfunction = 'numbamodule.numba_function'
module = import_module(importfunction.split('.')[0])
function = getattr(module, importfunction.split('.')[-1])
while True:
print(str(name) + ' - executing Numba function...')
# Execute the function
function(10)
time.sleep(0.1)
if __name__ == '__main__':
processes = [Process(target=execute_numba, args=(i,)) for i in range(2)]
[p.start() for p in processes]
time.sleep(1)
[p.terminate() for p in processes]
numbamodule.py
Что определяет простую функцию numba_function
:
import numba
@numba.jit()
def numba_function(x):
total = 0
for i in range(x):
total += i
return total
Я могу запустить main.py
script и посмотреть, как печать обоих процессов:
$ python main.py
0 - executing Numba function...
1 - executing Numba function...
0 - executing Numba function...
1 - executing Numba function...
0 - executing Numba function...
1 - executing Numba function...
[...]
Ломать его
Как я его сломаю, это немного странно, но это то, на что я наткнулся, пытаясь свести к минимуму воспроизводимый тестовый пример. Пожалуйста, скажите мне, можете ли вы воспроизвести такое же поведение.
В main.py
я просто добавлю один из предлагаемых (ниже) импорт после последнего импорта Process
(то есть: раскомментируйте одну строку и попробуйте):
import time
from importlib import import_module
from multiprocessing import Process
#
# Adding one of the import lines bellow results in a block...
# (you may need to install the packages first in the virtual environment)
#
#import matplotlib
#import Pyro4
#import scipy
#import dill
def execute_numba(name):
# [...]
Затем один процесс может блокироваться в функции execute_numba
(в частности, при вызове import_module()
):
$ python main.py
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
1 - executing Numba function...
[...]
Для меня matplotlib
и Pyro4
импортирует "работу" лучше всего. Я даже не могу получить блок на 100% пробегов...: -/
Обратите внимание, что я просто добавляю одну строку импорта, а не фактически использую пакет. Некоторые другие внешние импорта также приводят к блоку, но я обнаружил, что предложенные выше "работают" лучше всего (блокируют большинство).
Что происходит?
Во-первых, можете ли вы воспроизвести одно и то же поведение? (специально заинтересованные в не виртуализированных машинах GNU/Linux)
Я не знаю, как отлаживать это или почему это может произойти. Любые идеи?
Тот факт, что добавление одного случайного import xxx
запускает блок, пугает меня и не имеет для меня никакого смысла. Может ли это зависеть от времени/задержки, и поэтому некоторые из них ломают его, а некоторые другие нет?
Примечания
- Как вы видите, нет трассировки, процесс просто блокирует.
- Если я удалю
import numba
и @numba.jit
из numbamodule.py
, тогда он всегда будет работать, возможно, он имеет какое-то отношение к Numba?
- Я могу воспроизвести такое же поведение и со старыми версиями Numba/Python. Пробовали с Numba 0.25.0 и 0.22.1 (оба с Python 3.5.3).
Обновления
- 2017-07-03: просто, чтобы было ясно, я не ищу обходного пути (у меня уже есть один в реальном коде). Я искренне заинтересован в том, как действовать в таком случае. Понимайте, что происходит, и узнайте, как отлаживать и находить проблему, чтобы сообщить об этом, если это сломанный пакет/сборка/среда. Как вы продолжите?
- 2017-07-10: Блок возникает, в частности, при вызове
import_module()
.
- 2017-07-11: Сообщить о выпуске Numba.
Ответы
Ответ 1
Это относится только к отладке matplotlib и действительно угадывает, но может помочь вам немного сократить проблему.
Вы можете запустить свою программу, включив matplotlib, с помощью
python main.py --verbose-helpful
который показывает отладочный вывод в инициализации matplotlib. Поскольку это звучало как проблема, которая присутствует только в вашей конкретной системе, может возникнуть проблема с конфигурацией, при которой matplotlibrc настроен таким образом, что он запускается в интерактивном режиме.
Ниже приведен обзор доступных режимов отладки:
https://matplotlib.org/users/customizing.html
Ответ 2
Здесь воспроизводится на официальной среде Pockon Docker. Dockerfile
следует (поместите ваши файлы .py
).
FROM python:3.5
RUN pip install numba matplotlib pyro4
ADD . /opt
WORKDIR /opt
CMD python main.py
Тогда:
docker build -t so-44764520 .
docker run --rm -it so-44764520
Оба работают одинаково, без "рабочего" импорта, matplotlib
и Pyro4
, а с ними - в main.py
.