# 1.16。常见问题
> 原文: [http://numba.pydata.org/numba-doc/latest/user/faq.html](http://numba.pydata.org/numba-doc/latest/user/faq.html)
## 1.16.1。编程
### 1.16.1.1。我可以将函数作为参数传递给 jitted 函数吗?
从 Numba 0.39 开始,你可以,只要函数参数也被 JIT 编译:
```py
@jit(nopython=True)
def f(g, x):
return g(x) + g(-x)
result = f(jitted_g_function, 1)
```
但是,使用作为函数的参数进行调度会产生额外的开销。如果这对您的应用程序很重要,您还可以使用工厂函数来捕获闭包中的函数参数:
```py
def make_f(g):
# Note: a new f() is created each time make_f() is called!
@jit(nopython=True)
def f(x):
return g(x) + g(-x)
return f
f = make_f(jitted_g_function)
result = f(1)
```
提高 Numba 功能的调度性能是一项持续的任务。
### 1.16.1.2。当我修改全局变量 时,Numba 似乎并不关心
Numba 将全局变量视为编译时常量。如果您希望在修改全局变量值时自己的 jitted 函数自行更新,一种解决方案是使用 [`recompile()`](../reference/jit-compilation.html#Dispatcher.recompile "Dispatcher.recompile") 方法重新编译它。但这是一个相对较慢的操作,因此您可以决定重新构建代码并将全局变量转换为函数参数。
### 1.16.1.3。我可以调试 jitted 功能吗?
Numba 编译的代码目前不支持调用 [`pdb`](https://docs.python.org/3/library/pdb.html#module-pdb "(in Python v3.7)") 或其他此类高级设施。但是,您可以通过设置 [`NUMBA_DISABLE_JIT`](../reference/envvars.html#envvar-NUMBA_DISABLE_JIT) 环境变量来暂时禁用编译。
### 1.16.1.4。如何创建 Fortran 排序的数组?
Numba 目前不支持大多数 Numpy 函数的`order`参数,例如 [`numpy.empty()`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.empty.html#numpy.empty "(in NumPy v1.16)") (由于[类型推断](../glossary.html#term-type-inference)算法的限制)。您可以通过创建 C 有序数组然后转置它来解决此问题。例如:
```py
a = np.empty((3, 5), order='F')
b = np.zeros(some_shape, order='F')
```
可以改写为:
```py
a = np.empty((5, 3)).T
b = np.zeros(some_shape[::-1]).T
```
### 1.16.1.5。如何增加整数宽度?
默认情况下,Numba 通常使用整数变量的机器整数宽度。在 32 位机器上,您有时可能需要 64 位整数的大小。您可以简单地将相关变量初始化为`np.int64`(例如`np.int64(0)`而不是`0`)。它将传播到涉及这些变量的所有计算。
### 1.16.1.6。如何判断`parallel=True`是否有效?
将[环境变量](../reference/envvars.html#numba-envvars) `NUMBA_WARNINGS`设置为非零,如果`parallel=True`转换因装饰的功能失败,将显示警告。
此外,设置[环境变量](../reference/envvars.html#numba-envvars) `NUMBA_DEBUG_ARRAY_OPT_STATS`将显示有关哪些运算符/调用转换为并行 for 循环的一些统计信息。
## 1.16.2。表现
### 1.16.2.1。 Numba 内联功能吗?
Numba 为 LLVM 提供了足够的信息,因此可以内联足够短的函数。这仅适用于 [nopython 模式](../glossary.html#term-nopython-mode)。
### 1.16.2.2。 Numba 矢量化阵列计算(SIMD)吗?
Numba 本身并没有实现这样的优化,但它允许 LLVM 应用它们。
### 1.16.2.3。为什么我的循环没有矢量化?
Numba 默认启用 LLVM 中的循环向量化优化。虽然它是一个强大的优化,但并非所有循环都适用。有时,循环向量化可能会因内存访问模式等细微细节而失败。要从 LLVM 查看其他诊断信息,请添加以下行:
```py
import llvmlite.binding as llvm
llvm.set_option('', '--debug-only=loop-vectorize')
```
这告诉 LLVM 从 **loop-vectorize** 传递到 stderr 打印调试信息。每个函数条目如下所示:
```py
LV: Checking a loop in "<low-level symbol name>" from <function name>
LV: Loop hints: force=? width=0 unroll=0
...
LV: Vectorization is possible but not beneficial.
LV: Interleaving is not beneficial.
```
每个函数条目由空行分隔。拒绝矢量化的原因通常是在条目结束时。在上面的示例中,LLVM 拒绝了矢量化,因为这样做不会加速循环。在这种情况下,它可能是由于内存访问模式。例如,循环的数组可能不是连续的布局。
当内存访问模式不重要,无法确定访问内存区域时,LLVM 可能会拒绝以下消息:
```py
LV: Can't vectorize due to memory conflicts
```
另一个常见原因是:
```py
LV: Not vectorizing: loop did not meet vectorization requirements.
```
在这种情况下,矢量化被拒绝,因为矢量化代码可能表现不同。这是尝试打开`fastmath=True`以允许 fastmath 指令的情况。
### 1.16.2.4。 Numba 会自动并行化代码吗?
在某些情况下,它可以:
* 具有`target="parallel"`选项的 Ufuncs 和 gufunc 将在多个线程上运行。
* `@jit`的`parallel=True`选项将尝试优化阵列操作并并行运行。它还增加了对`prange()`的支持,以显式并行化循环。
您也可以自己在多个线程上手动运行计算并使用`nogil=True`选项(参见[释放 GIL](jit.html#jit-nogil) )。 Numba 还可以使用其 CUDA 和 HSA 后端在 GPU 架构上实现并行执行。
### 1.16.2.5。 Numba 可以加快短期运行功能吗?
不显着。新用户有时希望 JIT 编译这样的函数:
```py
def f(x, y):
return x + y
```
并获得 Python 解释器的显着加速。但是 Numba 没有太多可以改进的地方:大部分时间都可能花在 CPython 的函数调用机制上,而不是函数本身。根据经验,如果函数执行时间不到 10μs:请保留它。
例外情况是你应该 JIT 编译该函数,如果它是从另一个 jitted 函数调用的。
### 1.16.2.6。当 JIT 编译一个复杂的函数时有一个延迟,我该如何改进呢?
尝试将`cache=True`传递给`@jit`装饰器。它会将编译后的版本保留在磁盘上供以后使用。
更激进的替代方案是[提前编译](pycc.html#pycc)。
## 1.16.3。 GPU 编程
### 1.16.3.1。如何解决`CUDA intialized before forking`错误?
在 Linux 上,Python 标准库中的`multiprocessing`模块默认使用`fork`方法创建新进程。由于在父进程和子进程之间分配重复状态的进程,如果 CUDA 运行时在之前被初始化到 fork,CUDA 将无法在子进程中正常工作。 Numba 检测到这一点并使用`CUDA initialized before forking`消息引发`CudaDriverError`。
避免此错误的一种方法是在子进程内或创建进程池后对`numba.cuda`函数进行所有调用。但是,这并不总是可行,因为您可能希望在启动进程池之前查询可用 GPU 的数量。在 Python 3 中,您可以更改进程启动方法,如[多处理文档](https://docs.python.org/3.6/library/multiprocessing.html#contexts-and-start-methods)中所述。从`fork`切换到`spawn`或`forkserver`将避免 CUDA 初始化问题,尽管子进程不会从其父进程继承任何全局变量。
## 1.16.4。与其他工具集成
### 1.16.4.1。我可以“冻结”使用 Numba 的应用程序吗?
如果您使用 PyInstaller 或类似的实用程序来冻结应用程序,则可能会遇到 llvmlite 的问题。 llvmlite 需要一个非 Python DLL 才能正常工作,但冻结实用程序不会自动检测到它。您必须通知冻结实用程序 DLL 的位置:它通常会被命名为`llvmlite/binding/libllvmlite.so`或`llvmlite/binding/llvmlite.dll`,具体取决于您的系统。
### 1.16.4.2。在 Spyder 下运行两次脚本时出错
当您在 Spyder 下的控制台中运行脚本时,Spyder 会首先尝试重新加载现有模块。这对 Numba 不起作用,并且可能产生`TypeError: No matching definition for argument type(s)`之类的错误。
Spyder 首选项中有一个修复程序。打开“首选项”窗口,选择“控制台”,然后选择“高级设置”,单击“设置 UMR 排除模块”按钮,并在弹出的文本框内添加`numba`。
要查看设置是否生效,请确保重新启动 IPython 控制台或内核。
### 1.16.4.3。为什么 Numba 抱怨当前的语言环境?
如果收到如下错误消息:
```py
RuntimeError: Failed at nopython (nopython mode backend)
LLVM will produce incorrect floating-point code in the current locale
```
这意味着您遇到了 LLVM 错误,导致浮点常量处理不正确。已知某些第三方库(如 Qt 后端到 matplotlib)会发生这种情况。
要解决此问题,您需要将语言环境强制恢复为其默认值,例如:
```py
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
```
## 1.16.5。杂项
### 1.16.5.1。如何在其他工作中引用/引用/确认 Numba?
对于学术用途,最好的选择是引用我们的 ACM 程序: [Numba:基于 LLVM 的 Python JIT 编译器。](http://dl.acm.org/citation.cfm?id=2833162&dl=ACM&coll=DL)
- 1. 用户手册
- 1.1。 Numba 的约 5 分钟指南
- 1.2。概述
- 1.3。安装
- 1.4。使用@jit 编译 Python 代码
- 1.5。使用@generated_jit 进行灵活的专业化
- 1.6。创建 Numpy 通用函数
- 1.7。用@jitclass 编译 python 类
- 1.8。使用@cfunc 创建 C 回调
- 1.9。提前编译代码
- 1.10。使用@jit 自动并行化
- 1.11。使用@stencil装饰器
- 1.12。从 JIT 代码 中回调到 Python 解释器
- 1.13。性能提示
- 1.14。线程层
- 1.15。故障排除和提示
- 1.16。常见问题
- 1.17。示例
- 1.18。会谈和教程
- 2. 参考手册
- 2.1。类型和签名
- 2.2。即时编译
- 2.3。提前编译
- 2.4。公用事业
- 2.5。环境变量
- 2.6。支持的 Python 功能
- 2.7。支持的 NumPy 功能
- 2.8。与 Python 语义的偏差
- 2.9。浮点陷阱
- 2.10。 Python 2.7 寿命终止计划
- 3. 用于 CUDA GPU 的 Numba
- 3.1。概述
- 3.2。编写 CUDA 内核
- 3.3。内存管理
- 3.4。编写设备功能
- 3.5。 CUDA Python 中支持的 Python 功能
- 3.6。支持的原子操作
- 3.7。随机数生成
- 3.8。设备管理
- 3.10。示例
- 3.11。使用 CUDA 模拟器 调试 CUDA Python
- 3.12。 GPU 减少
- 3.13。 CUDA Ufuncs 和广义 Ufuncs
- 3.14。共享 CUDA 内存
- 3.15。 CUDA 阵列接口
- 3.16。 CUDA 常见问题
- 4. CUDA Python 参考
- 4.1。 CUDA 主机 API
- 4.2。 CUDA 内核 API
- 4.3。内存管理
- 5. 用于 AMD ROC GPU 的 Numba
- 5.1。概述
- 5.2。编写 HSA 内核
- 5.3。内存管理
- 5.4。编写设备功能
- 5.5。支持的原子操作
- 5.6。代理商
- 5.7。 ROC Ufuncs 和广义 Ufuncs
- 5.8。示例
- 6. 扩展 Numba
- 6.1。高级扩展 API
- 6.2。低级扩展 API
- 6.3。示例:间隔类型
- 7. 开发者手册
- 7.1。贡献给 Numba
- 7.2。 Numba 建筑
- 7.3。多态调度
- 7.4。关于发电机的注意事项
- 7.5。关于 Numba Runtime 的注意事项
- 7.6。使用 Numba Rewrite Pass 获得乐趣和优化
- 7.7。实时变量分析
- 7.8。上市
- 7.9。模板注释
- 7.10。关于自定义管道的注意事项
- 7.11。环境对象
- 7.12。哈希 的注意事项
- 7.13。 Numba 项目路线图
- 8. Numba 增强建议
- 9. 术语表