如何在numba

时间:2017-05-23 10:03:11

标签: anaconda numba

我有一个用numba编写的相当大的代码库,我注意到当为另一个文件中调用另一个numba编译函数的函数启用缓存时,调用被调用函数时不会调用被调用函数的变化。当我有两个文件时会出现这种情况:

testfile2:

import numba

@numba.njit(cache=True)
def function1(x):
    return x * 10

testfile的:

import numba
from tests import file1

@numba.njit(cache=True)
def function2(x, y):
    return y + file1.function1(x)

如果在jupyter笔记本中,我运行以下内容:

# INSIDE JUPYTER NOTEBOOK
import sys
sys.path.insert(1, "path/to/files/")
from tests import testfile

testfile.function2(3, 4)
>>> 34   # good value

但是,如果我更改,则将testfile2更改为以下内容:

import numba

@numba.njit(cache=True)
def function1(x):
    return x * 1

然后我重新启动jupyter笔记本内核并重新运行笔记本,我得到以下内容

import sys
sys.path.insert(1, "path/to/files/")
from tests import testfile

testfile.function2(3, 4)
>>> 34   # bad value, should be 7

将两个文件导入笔记本对不良结果没有影响。此外,仅在cache=False上设置function1也无效。什么工作是在所有njit'ted函数上设置cache=False,然后重新启动内核,然后重新运行。

我相信LLVM可能会内联一些被调用的函数,然后再也不会再检查它们了。

我查看了源代码并发现有一个方法返回缓存对象numba.caching.NullCache(),实例化缓存对象并运行以下内容:

cache = numba.caching.NullCache()
cache.flush()

不幸的是,似乎没有效果。

是否存在numba环境设置,或者我可以手动清除conda env中所有缓存函数的其他方式?或者我只是做错了什么?

我在Mac OS X 10.12.3上使用Anaconda Python 3.6运行numba 0.33。

2 个答案:

答案 0 :(得分:2)

这有点像黑客,但它是我以前用过的东西。如果你把这个函数放在你的numba函数的顶层(对于这个例子,在testfile中),它应该重新编译所有东西:

import inspect
import sys

def recompile_nb_code():
    this_module = sys.modules[__name__]
    module_members = inspect.getmembers(this_module)

    for member_name, member in module_members:
        if hasattr(member, 'recompile') and hasattr(member, 'inspect_llvm'):
            member.recompile()

然后在您想要强制重新编译时从您的jupyter笔记本中调用它。需要注意的是,它只适用于此函数所在模块中的文件及其依赖项。可能有另一种方式来概括它。

答案 1 :(得分:1)

在看到Josh的答案之后,通过在项目方法中创建一个实用程序来杀死缓存,我用一个黑客解决方案解决了这个问题。

可能有更好的方法,但这有效。我打开这个问题,万一有人不那么讨厌这样做。

import os


def kill_files(folder):
    for the_file in os.listdir(folder):
        file_path = os.path.join(folder, the_file)
        try:
            if os.path.isfile(file_path):
                os.unlink(file_path)
        except Exception as e:
            print("failed on filepath: %s" % file_path)


def kill_numba_cache():

    root_folder = os.path.realpath(__file__ + "/../../")

    for root, dirnames, filenames in os.walk(root_folder):
        for dirname in dirnames:
            if dirname == "__pycache__":
                try:
                    kill_files(root + "/" + dirname)
                except Exception as e:
                    print("failed on %s", root)