怪异的多处理块导入numba函数



环境

  • GNU/Linux(Fedora 25(。
  • conda环境。
  • python 3.6.1。
  • numba 0.33.0(np112py36_0(。

初始设置(正常工作(

两个文件main.pynumbamodule.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...
[...]

对我来说,matplotlibPyro4导入"工作"最好。我什至无法获得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页中被承认。

现在似乎已修复。如果您遇到此问题,请更新您的numballvmlite安装。如果那无法解决问题,您可能应该在该问题中添加评论以重新打开它。

@stuartarchibald评论:

[...]看来一个处理已被阻止是因为它在实际事实中具有segfaulted [...]

[...]从该位置出现的segfaults几乎总是由于线程在LLVM内部执行并发操作,或者与Numba初始化序列期间安装功能有关的问题。[...]

[...]不能再用llvmlite==0.22.0dev0numba==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

两者都以相同的方式工作,而没有"工作"导入,matplotlibPyro4,以及在main.py中使用它们。

最新更新