Numpy 数组形状未被 numba 识别为 int
Numpy array shape not recognized as int by numba
我想基于一些数组生成一个 numpy 矩阵,并使用 jit
或理想情况下 njit
来加速这一生成。如果 nopython=False
(启用 nopython
失败),它会继续发送我无法理解的 2 个以下警告:
:14: NumbaWarning: Compilation is
falling back to object mode WITH looplifting enabled because Function
"process_stuffs" failed type inference due to: No conversion from
array(int32, 2d, C) to array(int64, 2d, A) for 'inp', defined at None
File "", line 23: def
process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
^
During: typing of argument at (23)
File "", line 23: def
process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
^
@jit(nopython=False, :14:
NumbaWarning: Compilation is falling back to object mode WITHOUT
looplifting enabled because Function "process_stuffs" failed type
inference due to: Cannot determine Numba type of <class
'numba.core.dispatcher.LiftedLoop'>
File "", line 25: def
process_stuffs(output,inp,route1, route2, zoneidx):
for minute in range(input_pallets):
^
@jit(nopython=False,
C:\Anaconda3\envs\dev38\lib\site-packages\numba\core\object_mode_passes.py:151:
NumbaWarning: Function "process_stuffs" was compiled in object mode
without forceobj=True, but has lifted loops.
尽管该函数确实使用了复杂类型,但在确定 inp
数组的长度时,它在 非常 开始时失败,然后它不会想生成一个循环,虽然我已经看到了很多例子。
我试图通过使用 locals
指定类型来更正错误,但如您所见,它没有帮助。
这是一个最小的工作代码:
zoneidx=Dict.empty(key_type=types.unicode_type,value_type=types.int8)
zoneidx["A"]=np.int8(0)
zoneidx["B"]=np.int8(1)
zoneidx["C"]=np.int8(2)
zoneidx["D"]=np.int8(3)
zoneidx["E"]=np.int8(4)
output = np.zeros(shape=(110,5),dtype=np.int64)
inp = np.random.randint(0,2,size=(100,2))
route1 = np.random.choice(list('ABCDE'),size=10)
route2 = np.random.choice(list('ABCDE'),size=10)
@jit(nopython=False,
locals={'input_pallets':numba.int64,
'step':numba.int64,
'inp':numba.types.int64[:,:],
'route1':numba.types.unicode_type[:],
'route2':numba.types.unicode_type[:],
'output':numba.types.int64[:,:]})
def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
for minute in range(input_pallets):
prod1, prod2 = inp[minute]
if prod1+prod2 <1:
continue
if prod1:
routing = route1
number_of_pallets = prod1
number_of_steps = route1.shape[0]
else:
routing = route2
number_of_pallets = prod2
number_of_steps = route2.shape[0]
for step in range(number_of_steps):
zone = routing[step]
output[minute+step,zoneidx[zone]]+=number_of_pallets
return output
numba.__version__ == 0.53.1
numpy.__version__ == 1.19.2
我的代码有什么问题?
注意:我对代码输出的正确性不感兴趣,我知道一旦“inp”激活“route1”,“route2”就会被忽略。我只想编译它。
警告信息具有误导性。事实上输入的类型确实没有正确给出,它与.shape
方法无关。
我的解决方案是使用 numba.typeof
函数来告诉它期望的类型。例如。预期是 int32,而不是“inp”的 64。并且“unichr”是预期的,而不是 unicode。
这是我的最小示例的工作版本:
zoneidx=Dict.empty(key_type=numba.typeof(route1).dtype,value_type=types.int8)
zoneidx["A"]=np.int8(0)
zoneidx["B"]=np.int8(1)
zoneidx["C"]=np.int8(2)
zoneidx["D"]=np.int8(3)
zoneidx["E"]=np.int8(4)
output = np.zeros(shape=(110,5),dtype=np.int64)
inp = np.random.randint(0,2,size=(100,2))
route1 = np.random.choice(list('ABCDE'),size=10)
route2 = np.random.choice(list('ABCDE'),size=10)
@jit(nopython=False,
locals={'input_pallets':numba.int64,
'step':numba.int64,
'inp':numba.types.int32[:,:],
'route1':numba.typeof(route1),
'route2':numba.typeof(route1),
'output':numba.types.int64[:,:]})
def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
for minute in range(input_pallets):
prod1, prod2 = inp[minute]
if prod1+prod2 <1:
continue
if prod1:
routing = route1
number_of_pallets = prod1
number_of_steps = route1.shape[0]
else:
routing = route2
number_of_pallets = prod2
number_of_steps = route2.shape[0]
for step in range(number_of_steps):
zone = routing[step]
output[minute+step,zoneidx[zone]]+=number_of_pallets
return output
我想基于一些数组生成一个 numpy 矩阵,并使用 jit
或理想情况下 njit
来加速这一生成。如果 nopython=False
(启用 nopython
失败),它会继续发送我无法理解的 2 个以下警告:
:14: NumbaWarning: Compilation is falling back to object mode WITH looplifting enabled because Function "process_stuffs" failed type inference due to: No conversion from array(int32, 2d, C) to array(int64, 2d, A) for 'inp', defined at None
File "", line 23: def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape ^
During: typing of argument at (23)
File "", line 23: def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape ^
@jit(nopython=False, :14: NumbaWarning: Compilation is falling back to object mode WITHOUT looplifting enabled because Function "process_stuffs" failed type inference due to: Cannot determine Numba type of <class 'numba.core.dispatcher.LiftedLoop'>
File "", line 25: def process_stuffs(output,inp,route1, route2, zoneidx):
for minute in range(input_pallets): ^
@jit(nopython=False, C:\Anaconda3\envs\dev38\lib\site-packages\numba\core\object_mode_passes.py:151: NumbaWarning: Function "process_stuffs" was compiled in object mode without forceobj=True, but has lifted loops.
尽管该函数确实使用了复杂类型,但在确定 inp
数组的长度时,它在 非常 开始时失败,然后它不会想生成一个循环,虽然我已经看到了很多例子。
我试图通过使用 locals
指定类型来更正错误,但如您所见,它没有帮助。
这是一个最小的工作代码:
zoneidx=Dict.empty(key_type=types.unicode_type,value_type=types.int8)
zoneidx["A"]=np.int8(0)
zoneidx["B"]=np.int8(1)
zoneidx["C"]=np.int8(2)
zoneidx["D"]=np.int8(3)
zoneidx["E"]=np.int8(4)
output = np.zeros(shape=(110,5),dtype=np.int64)
inp = np.random.randint(0,2,size=(100,2))
route1 = np.random.choice(list('ABCDE'),size=10)
route2 = np.random.choice(list('ABCDE'),size=10)
@jit(nopython=False,
locals={'input_pallets':numba.int64,
'step':numba.int64,
'inp':numba.types.int64[:,:],
'route1':numba.types.unicode_type[:],
'route2':numba.types.unicode_type[:],
'output':numba.types.int64[:,:]})
def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
for minute in range(input_pallets):
prod1, prod2 = inp[minute]
if prod1+prod2 <1:
continue
if prod1:
routing = route1
number_of_pallets = prod1
number_of_steps = route1.shape[0]
else:
routing = route2
number_of_pallets = prod2
number_of_steps = route2.shape[0]
for step in range(number_of_steps):
zone = routing[step]
output[minute+step,zoneidx[zone]]+=number_of_pallets
return output
numba.__version__ == 0.53.1
numpy.__version__ == 1.19.2
我的代码有什么问题?
注意:我对代码输出的正确性不感兴趣,我知道一旦“inp”激活“route1”,“route2”就会被忽略。我只想编译它。
警告信息具有误导性。事实上输入的类型确实没有正确给出,它与.shape
方法无关。
我的解决方案是使用 numba.typeof
函数来告诉它期望的类型。例如。预期是 int32,而不是“inp”的 64。并且“unichr”是预期的,而不是 unicode。
这是我的最小示例的工作版本:
zoneidx=Dict.empty(key_type=numba.typeof(route1).dtype,value_type=types.int8)
zoneidx["A"]=np.int8(0)
zoneidx["B"]=np.int8(1)
zoneidx["C"]=np.int8(2)
zoneidx["D"]=np.int8(3)
zoneidx["E"]=np.int8(4)
output = np.zeros(shape=(110,5),dtype=np.int64)
inp = np.random.randint(0,2,size=(100,2))
route1 = np.random.choice(list('ABCDE'),size=10)
route2 = np.random.choice(list('ABCDE'),size=10)
@jit(nopython=False,
locals={'input_pallets':numba.int64,
'step':numba.int64,
'inp':numba.types.int32[:,:],
'route1':numba.typeof(route1),
'route2':numba.typeof(route1),
'output':numba.types.int64[:,:]})
def process_stuffs(output,inp,route1, route2, zoneidx):
input_pallets, _ = inp.shape
for minute in range(input_pallets):
prod1, prod2 = inp[minute]
if prod1+prod2 <1:
continue
if prod1:
routing = route1
number_of_pallets = prod1
number_of_steps = route1.shape[0]
else:
routing = route2
number_of_pallets = prod2
number_of_steps = route2.shape[0]
for step in range(number_of_steps):
zone = routing[step]
output[minute+step,zoneidx[zone]]+=number_of_pallets
return output