这段代码有什么问题?模块类型的未知属性 'array'(<module 'numpy' from filename __init__.py'>
What's wrong in this code? Unknown attribute 'array' of type Module(<module 'numpy' from filename __init__.py'>
我正在尝试使用@vectorize 在函数内创建一个数组,我不知道为什么我一直收到此错误:
Unknown attribute 'array' of type Module( < module 'numpy' from 'filename.... /lib/python3.6/site-packages/numpy/ __ init __ .py'>)
代码:
from numba import vectorize, float32
import numpy as np
@vectorize([float32(float32[:,:], float32[:])], target='cuda')
def fitness(vrp_data, individual):
# The first distance is from depot to the first node of the first route
depot = np.array([0.0, 0.0, 30.0, 40.0], dtype=np.float32)
firstnode = np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32)
firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if
individual[0] !=0 else depot
x1 = depot[2]
x2 = firstnode[2]
y1 = depot[3]
y2 = firstnode[3]
dx = x1 - x2
dy = y1 - y2
totaldist = math.sqrt(dx * dx + dy * dy)
return totaldist
代码在没有函数修饰的情况下工作正常。
问题
Numba 不支持 numpy.array
。 Numba 仅支持 Numpy 顶级函数的一个子集(即您调用的任何函数,如 numpy.foo
)。这是一个 identical issue from the Numba bug tracker.
"solution"
这是 list of Numpy functions that Numba actually supports。支持 numpy.zeros
,因此在理想情况下,您只需将代码中使用 np.array
的行更改为:
depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)
它会起作用的。但是,当定位 cuda
all Numpy functions that allocate memory (including np.zeros
) are disabled 时。所以你必须想出一个不涉及任何数组分配的解决方案。
使用 vectorize
的问题
此外,vectorize
似乎不是您应该使用的包装函数。相反,一个类似于您编写的函数 requires the use of guvectorize
。这是我能够开始工作的与您的原始代码最接近的东西:
import math
from numba import guvectorize, float32
import numpy as np
@guvectorize([(float32[:,:], float32[:], float32[:])], '(m,n),(p)->()')
def fitness(vrp_data, individual, totaldist):
# The first distance is from depot to the first node of the first route
depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)
firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if individual[0] !=0 else depot
x1 = depot[2]
x2 = firstnode[2]
y1 = depot[3]
y2 = firstnode[3]
dx = x1 - x2
dy = y1 - y2
totaldist[0] = math.sqrt(dx * dx + dy * dy)
签名中的第三个参数实际上是 return 值,因此您可以这样调用该函数:
vrp_data = np.arange(100, 100 + 4*4, dtype=np.float32).reshape(4,4)
individual = np.arange(100, 104, dtype=np.float32)
fitness(vrp_data, individual)
输出:
95.67131
最新 Numba 中更好的错误消息
您可能应该升级您的 Numba 版本。在当前版本中,您的原始代码会引发更具体的错误消息:
TypingError: Failed in nopython mode pipeline (step: nopython frontend). Use of unsupported NumPy function 'numpy.array' or unsupported use of the function.
我正在尝试使用@vectorize 在函数内创建一个数组,我不知道为什么我一直收到此错误:
Unknown attribute 'array' of type Module( < module 'numpy' from 'filename.... /lib/python3.6/site-packages/numpy/ __ init __ .py'>)
代码:
from numba import vectorize, float32
import numpy as np
@vectorize([float32(float32[:,:], float32[:])], target='cuda')
def fitness(vrp_data, individual):
# The first distance is from depot to the first node of the first route
depot = np.array([0.0, 0.0, 30.0, 40.0], dtype=np.float32)
firstnode = np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32)
firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if
individual[0] !=0 else depot
x1 = depot[2]
x2 = firstnode[2]
y1 = depot[3]
y2 = firstnode[3]
dx = x1 - x2
dy = y1 - y2
totaldist = math.sqrt(dx * dx + dy * dy)
return totaldist
代码在没有函数修饰的情况下工作正常。
问题
Numba 不支持numpy.array
。 Numba 仅支持 Numpy 顶级函数的一个子集(即您调用的任何函数,如 numpy.foo
)。这是一个 identical issue from the Numba bug tracker.
"solution"
这是 list of Numpy functions that Numba actually supports。支持 numpy.zeros
,因此在理想情况下,您只需将代码中使用 np.array
的行更改为:
depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)
它会起作用的。但是,当定位 cuda
all Numpy functions that allocate memory (including np.zeros
) are disabled 时。所以你必须想出一个不涉及任何数组分配的解决方案。
使用 vectorize
的问题
此外,vectorize
似乎不是您应该使用的包装函数。相反,一个类似于您编写的函数 requires the use of guvectorize
。这是我能够开始工作的与您的原始代码最接近的东西:
import math
from numba import guvectorize, float32
import numpy as np
@guvectorize([(float32[:,:], float32[:], float32[:])], '(m,n),(p)->()')
def fitness(vrp_data, individual, totaldist):
# The first distance is from depot to the first node of the first route
depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)
firstnode = vrp_data[vrp_data[:,0] == individual[0]][0] if individual[0] !=0 else depot
x1 = depot[2]
x2 = firstnode[2]
y1 = depot[3]
y2 = firstnode[3]
dx = x1 - x2
dy = y1 - y2
totaldist[0] = math.sqrt(dx * dx + dy * dy)
签名中的第三个参数实际上是 return 值,因此您可以这样调用该函数:
vrp_data = np.arange(100, 100 + 4*4, dtype=np.float32).reshape(4,4)
individual = np.arange(100, 104, dtype=np.float32)
fitness(vrp_data, individual)
输出:
95.67131
最新 Numba 中更好的错误消息
您可能应该升级您的 Numba 版本。在当前版本中,您的原始代码会引发更具体的错误消息:
TypingError: Failed in nopython mode pipeline (step: nopython frontend). Use of unsupported NumPy function 'numpy.array' or unsupported use of the function.