# 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. 術語表