奇怪的多处理块导入Numba函数

时间:2017-06-26 16:41:38

标签: python 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导入后添加一个建议的(波纹管)导入(即:取消注释一行并尝试):

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触发块的事实让我害怕,对我来说没什么意义。这可能取决于时间/延迟,这就是为什么一些进口打破它而另一些则没有?

注释

  • 如你所见,没有追溯,这个过程只是阻止。
  • 如果我从import numba删除@numba.jitnumbamodule.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 issue acknowledged

3 个答案:

答案 0 :(得分:1)

这似乎是一个Numba bug,在issue 2431中得到承认。

现在似乎已经修好了。如果碰到这一点,请更新numballvmlite次安装。如果这不能解决问题,您可能应该在该问题中添加注释以重新打开它。

正如@stuartarchibald所评论的那样:

  

[...]看起来处理被阻止是因为它实际上已经被隔离[...]

     

[...]从这个位置出现的Segfault几乎总是由于线程在LLVM内执行并发操作,或者在Numba的初始化序列期间安装函数的一些问题。 [...]

     

[...]无法再使用llvmlite==0.22.0dev0numba==0.37.0.dev [...]

重现

答案 1 :(得分:0)

这仅适用于matplotlib调试,并且真的在猜测,但可能会帮助您缩小问题范围。

您可以在包含matplotlib的情况下启动程序:

python main.py --verbose-helpful

显示matplotlib初始化的调试输出。由于它听起来像是一个只存在于您的特定系统上的问题,因此可能会出现一些配置问题,即matplotlibrc以交互模式启动的方式配置。

以下是可用调试模式的概述: https://matplotlib.org/users/customizing.html

答案 2 :(得分:-1)

这是在官方Python Docker环境中的再现。 jdk-9-175跟随(放在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中的导入。