环境
- 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
脚本并查看两个过程打印:
$ 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
导入之后添加了提议的(bellow(导入(即:uncomment onemoment in Line and try(:
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
触发块的事实使我害怕,对我来说毫无意义。这可能取决于时间/延迟,这就是为什么有些进口会破坏它,而另一些进口却不呢?
注释
- 您可以看到没有追溯,该过程只是块。
- 如果我从
numbamodule.py
中删除import numba
和@numba.jit
,那么它将始终工作,因此也许与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问题。
看来这是一个numba错误,在第2431页中被承认。
现在似乎已修复。如果您遇到此问题,请更新您的numba
和llvmlite
安装。如果那无法解决问题,您可能应该在该问题中添加评论以重新打开它。
@stuartarchibald评论:
[...]看来一个处理已被阻止是因为它在实际事实中具有segfaulted [...]
[...]从该位置出现的segfaults几乎总是由于线程在LLVM内部执行并发操作,或者与Numba初始化序列期间安装功能有关的问题。[...]
[...]不能再用
再现llvmlite==0.22.0dev0
和numba==0.37.0.dev
[...]
这仅适用于matplotlib调试,并且确实在猜测,但可能会帮助您缩小问题。
包括matplotlib时,您可以使用:
来启动程序python main.py --verbose-helpful
显示您在matplotlib初始化上调试输出。由于它听起来像是一个仅在您的特定系统上存在的问题,因此可能会出现一些配置问题,其中Matplotlibrc以这种方式以交互式模式开始。
这是可用调试模式的概述:https://matplotlib.org/users/customizing.html
这是对Python 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
中使用它们。