意外的导入行为:导入了不存在的模块

Unexpected import behavior: non-existing module imported

我有一个 torch 扩展(但我​​认为我得到的错误与 torch 无关),我们称它为 foo,它是用 setuptools 构建的。但是,这取决于系统中是否有可用的 GPU,在这种情况下会编译一些 CUDA 代码:

from torch.utils.cpp_extension import CppExtension, BuildExtension, CUDAExtension

if cuda_available:
    ext = CUDAExtension(
            'foo_gpu',
            prefixed(prefix, ['foo.cpp', 'foo_kernel.cu']),
            define_macros=[('COMPILE_CUDA', '1')])
else:
    ext = CppExtension(
            'foo_cpu',
            prefixed(prefix, ['foo.cpp']))

setup(name=ext.name,
      version='1.0.0',
      ext_modules=[ext_module],
      extra_compile_args=['-mmacosx-version-min=10.9'],
      cmdclass={'build_ext': BuildExtension})

注意模块是如何编译为 foo_gpufoo_cpu.

后来我导入如下:

try:
    import foo_gpu as foo_backend
    CUDA_SUPPORTED = True
except ImportError:
    CUDA_SUPPORTED = False
    # Try importing the cpu version
    try:
        import foo_cpu as foo_backend
    except ImportError:
        ...

假设我用 CUDA 支持编译它,所以 foo_gpu 进入 PIP(实际上进入 PIP 为 foo-gpu,不知道为什么?)

现在,我卸载了它,pip uninstall foo-gpu,编译它只支持 CPU,pip 显示 foo-cpu 1.0.0.

BUT,现在,当我 运行 上面的导入代码时,它仍然找到 foo-gpu,即第一个导入语句成功!即使它没有出现在 pip.


编辑。我检查了 sys.path,发现我的 conda env 中有一个文件夹包含带有 gpu 的内容:

$ ls ~/miniconda3/envs/cpu_env/lib/python3.7/site-packages/foo_cpu-1.0.0-py3.7-linux-x86_64.egg/ 
 EGG-INFO
 __pycache__
 foo_cpu.cpython-37m-x86_64-linux-gnu.so
 foo_cpu.py
 foo_gpu.cpython-37m-x86_64-linux-gnu.so

但是它应该如何到达那里呢?在这个环境 (cpu_env) 中,我从未使用 GPU 支持进行编译。是否有一些缓存被调用?

事实证明 GPU 内置由设置工具(build/dist/ 等)缓存并安装!