Numba报错: NumbaTypeError: Cannot modify readonly array of type
一、报错重现
File "D:\Python3.7\lib\site-packages\numba\core\dispatcher.py", line 409, in error_rewrite
raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<built-in function setitem>) found for signature:
>>> setitem(readonly array(float64, 1d, C), int64, int64)
There are 16 candidate implementations:
- Of which 14 did not match due to:
Overload of function 'setitem': File: <numerous>: Line N/A.
With argument(s): '(readonly array(float64, 1d, C), int64, int64)':
No match.
- Of which 2 did not match due to:
Overload in function 'SetItemBuffer.generic': File: numba\core\typing\arraydecl.py: Line 176.
With argument(s): '(readonly array(float64, 1d, C), int64, int64)':
Rejected as the implementation raised a specific error:
NumbaTypeError: Cannot modify readonly array of type: readonly array(float64, 1d, C)
raised from D:\Python3.7\lib\site-packages\numba\core\typing\arraydecl.py:183
During: typing of setitem at d:/大学/课外项目、比赛、学习/2022车队/2022百度创意/edgeboard相关/roadtrace/compare.py (21)
File "compare.py", line 21:
def fun1():
<source elided>
if a[i][j] < 1.0:
a[i][j] = int(j)
^
报错的代码:
import numpy as np
import time
NUM = 160
from numba import jit
a=np.random.random((NUM,NUM))
@jit(nopython=True)
def fun1():
global a
for i in range(NUM):
for j in range(NUM):
if a[i][j] < 1.0:
a[i][j] = int(j)
pass
for b in range(10):
start = time.time()
fun1()
end1 = time.time()
print("end1",end1-start)
print("---")
原因探究
1、 数据类型不匹配
With argument(s): ‘(readonly array(float64, 1d, C), int64, int64)’:
No match.
第一个报错信息说明可能是数据类型不匹配。报错的位置在a[i][j] = int(j)
readonly array(float64,1d,C)
:数组 a是float64
类型的,只读
int64
:指数组的下标的数据类型
int64
:指int(j)
然而我尝试修改int(j)
为float(j)
也是出现同样的问题。
2、全局变量的编译
注意到另一个报错信息是
NumbaTypeError: Cannot modify readonly array of type: readonly
明明我通过global 声明 a 数组是全局变量,为什么是只读不可以写呢?
通过查阅资料发现,numba在编译时,会把全局变量编译为常量,就是只读的,不能修改。
解决方法
通过参数传递的方式就可以对a数组进行读写操作。
即
@jit(nopython=True)
def fun1(a):
for i in range(NUM):
for j in range(NUM):
if a[i][j] < 1.0:
a[i][j] = float(j)
pass
这样就可以解决问题了!