Numba data type error: Cannot unify array
Numba data type error: Cannot unify array
我正在使用 Numba 加速一系列功能,如下所示。如果我将函数 PosMomentSingle
中的 step_size
变量设置为浮点数(例如 step_size = 0.5
),而不是整数(例如 step_size = 1.0
),我会收到以下错误:
Cannot unify array(float32, 1d, C) and array(float64, 1d, C) for 'axle_coords.2', defined at <ipython-input-182-37c789ca2187> (12)
File "<ipython-input-182-37c789ca2187>", line 12:
def nbSimpleSpanMoment(L, axles, spacings, step_size):
<source elided>
while np.min(axle_coords) < L:
我发现很难理解问题出在哪里,但我的猜测是 @jit
(nbSimpleSpanMoment
) 之后的函数有问题,数据类型不匹配。我尝试将所有变量设置为 float32,然后设置为 float64(例如 L = np.float32(L)
),但无论我尝试什么都会产生一组新的错误。由于错误消息非常含糊,我无法调试问题。有 numba 经验的人可以解释我在这里做错了什么吗?
我将我的代码放在下面以重现问题。
感谢您的帮助!
import numba as nb
import numpy as np
@nb.vectorize(nopython=True)
def nbvectMoment(L,x):
if x<L/2.0:
return 0.5*x
else:
return 0.5*(L-x)
@nb.jit(nopython=True)
def nbSimpleSpanMoment(L, axles, spacings, step_size):
travel = L + np.sum(spacings)
maxmoment = 0
axle_coords = -np.cumsum(spacings)
moment_inf = np.empty_like(axles)
while np.min(axle_coords) < L:
axle_coords = axle_coords + step_size
y = nbvectMoment(L,axle_coords)
for k in range(y.shape[0]):
if axle_coords[k] >=0 and axle_coords[k] <= L:
moment_inf[k] = y[k]
else:
moment_inf[k] = 0.0
moment = np.sum(moment_inf * axles)
if maxmoment < moment:
maxmoment = moment
return np.around(maxmoment,1)
def PosMomentSingle(current_axles, current_spacings):
data_list = []
for L in range (1,201):
L=float(L)
if L <= 40:
step_size = 0.5
else:
step_size = 0.5
axles = np.array(current_axles, dtype='f')
spacings = np.array(current_spacings, dtype='f')
axles_inv = axles[::-1]
spacings_inv = spacings[::-1]
spacings = np.insert(spacings,0,0)
spacings_inv = np.insert(spacings_inv,0,0)
left_to_right = nbSimpleSpanMoment(L, axles, spacings, step_size)
right_to_left = nbSimpleSpanMoment(L, axles_inv, spacings_inv, step_size)
data_list.append(max(left_to_right, right_to_left))
return data_list
load_effects = []
for v in range(14,31):
load_effects.append(PosMomentSingle([8, 32, 32], [14, v]))
load_effects = np.array(load_effects)
删除代码中的所有类型转换后,返回以下错误
TypingError: Cannot unify array(int64, 1d, C) and array(float64, 1d, C) for 'axle_coords.2'
这帮助我将错误追溯到 spacings
的 dtype
。在您的代码中,它初始化为 C 兼容 single
,这似乎与 python float32
不同,请参阅 here。将其更改为 np.float64
后,代码现在运行。
下面的代码现在可以运行并且不会再出现统一错误。
import numba as nb
import numpy as np
@nb.vectorize(nopython=True)
def nbvectMoment(L,x):
if x<L/2.0:
return 0.5*x
else:
return 0.5*(L-x)
@nb.jit(nopython=True)
def nbSimpleSpanMoment(L, axles, spacings, step_size):
travel = L + np.sum(spacings)
maxmoment = 0
axle_coords = -np.cumsum(spacings)
moment_inf = np.empty_like(axles)
while np.min(axle_coords) < L:
axle_coords = axle_coords + step_size
y = nbvectMoment(L,axle_coords)
for k in range(y.shape[0]):
if axle_coords[k] >=0 and axle_coords[k] <= L:
moment_inf[k] = y[k]
else:
moment_inf[k] = 0.0
moment = np.sum(moment_inf * axles)
if maxmoment < moment:
maxmoment = moment
return np.around(maxmoment,1)
def PosMomentSingle(current_axles, current_spacings):
data_list = []
for L in range (1,201):
L=float(L)
if L <= 40:
step_size = 0.5
else:
step_size = 0.5
axles = np.array(current_axles, np.float32)
spacings = np.array(current_spacings, dtype=np.float64)
axles_inv = axles[::-1]
spacings_inv = spacings[::-1]
spacings = np.insert(spacings,0,0)
spacings_inv = np.insert(spacings_inv,0,0)
left_to_right = nbSimpleSpanMoment(L, axles, spacings, step_size)
right_to_left = nbSimpleSpanMoment(L, axles_inv, spacings_inv, step_size)
data_list.append(max(left_to_right, right_to_left))
return data_list
load_effects = []
for v in range(14,31):
load_effects.append(PosMomentSingle([8, 32, 32], [14, v]))
load_effects = np.array(load_effects)
我正在使用 Numba 加速一系列功能,如下所示。如果我将函数 PosMomentSingle
中的 step_size
变量设置为浮点数(例如 step_size = 0.5
),而不是整数(例如 step_size = 1.0
),我会收到以下错误:
Cannot unify array(float32, 1d, C) and array(float64, 1d, C) for 'axle_coords.2', defined at <ipython-input-182-37c789ca2187> (12)
File "<ipython-input-182-37c789ca2187>", line 12:
def nbSimpleSpanMoment(L, axles, spacings, step_size):
<source elided>
while np.min(axle_coords) < L:
我发现很难理解问题出在哪里,但我的猜测是 @jit
(nbSimpleSpanMoment
) 之后的函数有问题,数据类型不匹配。我尝试将所有变量设置为 float32,然后设置为 float64(例如 L = np.float32(L)
),但无论我尝试什么都会产生一组新的错误。由于错误消息非常含糊,我无法调试问题。有 numba 经验的人可以解释我在这里做错了什么吗?
我将我的代码放在下面以重现问题。
感谢您的帮助!
import numba as nb
import numpy as np
@nb.vectorize(nopython=True)
def nbvectMoment(L,x):
if x<L/2.0:
return 0.5*x
else:
return 0.5*(L-x)
@nb.jit(nopython=True)
def nbSimpleSpanMoment(L, axles, spacings, step_size):
travel = L + np.sum(spacings)
maxmoment = 0
axle_coords = -np.cumsum(spacings)
moment_inf = np.empty_like(axles)
while np.min(axle_coords) < L:
axle_coords = axle_coords + step_size
y = nbvectMoment(L,axle_coords)
for k in range(y.shape[0]):
if axle_coords[k] >=0 and axle_coords[k] <= L:
moment_inf[k] = y[k]
else:
moment_inf[k] = 0.0
moment = np.sum(moment_inf * axles)
if maxmoment < moment:
maxmoment = moment
return np.around(maxmoment,1)
def PosMomentSingle(current_axles, current_spacings):
data_list = []
for L in range (1,201):
L=float(L)
if L <= 40:
step_size = 0.5
else:
step_size = 0.5
axles = np.array(current_axles, dtype='f')
spacings = np.array(current_spacings, dtype='f')
axles_inv = axles[::-1]
spacings_inv = spacings[::-1]
spacings = np.insert(spacings,0,0)
spacings_inv = np.insert(spacings_inv,0,0)
left_to_right = nbSimpleSpanMoment(L, axles, spacings, step_size)
right_to_left = nbSimpleSpanMoment(L, axles_inv, spacings_inv, step_size)
data_list.append(max(left_to_right, right_to_left))
return data_list
load_effects = []
for v in range(14,31):
load_effects.append(PosMomentSingle([8, 32, 32], [14, v]))
load_effects = np.array(load_effects)
删除代码中的所有类型转换后,返回以下错误
TypingError: Cannot unify array(int64, 1d, C) and array(float64, 1d, C) for 'axle_coords.2'
这帮助我将错误追溯到 spacings
的 dtype
。在您的代码中,它初始化为 C 兼容 single
,这似乎与 python float32
不同,请参阅 here。将其更改为 np.float64
后,代码现在运行。
下面的代码现在可以运行并且不会再出现统一错误。
import numba as nb
import numpy as np
@nb.vectorize(nopython=True)
def nbvectMoment(L,x):
if x<L/2.0:
return 0.5*x
else:
return 0.5*(L-x)
@nb.jit(nopython=True)
def nbSimpleSpanMoment(L, axles, spacings, step_size):
travel = L + np.sum(spacings)
maxmoment = 0
axle_coords = -np.cumsum(spacings)
moment_inf = np.empty_like(axles)
while np.min(axle_coords) < L:
axle_coords = axle_coords + step_size
y = nbvectMoment(L,axle_coords)
for k in range(y.shape[0]):
if axle_coords[k] >=0 and axle_coords[k] <= L:
moment_inf[k] = y[k]
else:
moment_inf[k] = 0.0
moment = np.sum(moment_inf * axles)
if maxmoment < moment:
maxmoment = moment
return np.around(maxmoment,1)
def PosMomentSingle(current_axles, current_spacings):
data_list = []
for L in range (1,201):
L=float(L)
if L <= 40:
step_size = 0.5
else:
step_size = 0.5
axles = np.array(current_axles, np.float32)
spacings = np.array(current_spacings, dtype=np.float64)
axles_inv = axles[::-1]
spacings_inv = spacings[::-1]
spacings = np.insert(spacings,0,0)
spacings_inv = np.insert(spacings_inv,0,0)
left_to_right = nbSimpleSpanMoment(L, axles, spacings, step_size)
right_to_left = nbSimpleSpanMoment(L, axles_inv, spacings_inv, step_size)
data_list.append(max(left_to_right, right_to_left))
return data_list
load_effects = []
for v in range(14,31):
load_effects.append(PosMomentSingle([8, 32, 32], [14, v]))
load_effects = np.array(load_effects)