Что не так в этом коде? Неизвестный атрибут '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.
Другие вопросы по тегам