如何清除 numba 中的缓存(或强制重新编译)

How to clear cache (or force recompilation) in numba

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

测试文件2:

import numba

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

测试文件:

import numba
from tests import file1

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

如果在 jupyter notebook 中,我 运行 以下内容:

# 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 notebook内核并重新运行笔记本,我得到以下

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

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

将这两个文件导入笔记本对错误的结果没有任何影响。此外,仅在 function1 上设置 cache=False 也没有任何效果。起作用的是在所有 njit'd 函数上设置 cache=False,然后重新启动内核,然后重新 运行ning.

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

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

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

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

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

我 运行ning numba 0.33 与 Anaconda Python 3.6 Mac OS X 10.12.3.

这有点乱七八糟,但我以前用过。如果将此函数放在 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 notebook 调用它。需要注意的是,它仅适用于此函数所在模块中的文件及其依赖项。可能有另一种方法来概括它。

在看到 Josh 的回答后,我 "solved" 通过在项目方法中创建一个实用程序来终止缓存来使用 hack 解决方案。

可能有更好的方法,但这行得通。我把这个问题悬而未决,以防有人用不那么老套的方式来做这件事。

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)