Что не так в этом коде? Неизвестный атрибут 'array' типа Module(<module 'numpy' из имени файла __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
Код прекрасно работает без декорирования функции.
1 ответ
Эта проблема
numpy.array
не поддерживается Numba. Numba поддерживает только подмножество функций верхнего уровня Numpy (т. Е. Любую функцию, которую вы вызываете, как numpy.foo
). Вот идентичная проблема с трекером ошибок Numba.
Решение"
Вот список функций Numpy, которые фактически поддерживает Numba. numpy.zeros
поддерживается, поэтому в идеальном мире вы можете просто изменить строки в вашем коде, которые используют np.array
чтобы:
depot = np.zeros(4, dtype=np.float32)
depot[2:] = [30, 40]
firstnode = np.zeros(4, dtype=np.float32)
и это будет работать. Однако при нацеливании cuda
все функции Numpy, которые выделяют память (включая np.zeros
) отключены. Таким образом, вам придется придумать решение, которое не предполагает какого-либо выделения массива.
Проблемы с использованием vectorize
Кроме того, это выглядит как vectorize
это не та функция-обертка, которую вы должны использовать. Вместо этого функция, подобная той, которую вы написали, требует использования 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)
Третий аргумент в сигнатуре на самом деле является возвращаемым значением, поэтому вы вызываете функцию следующим образом:
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.