Что не так в этом коде?Неизвестный атрибут «массив» типа Модуль ( - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь создать массив внутри функции, используя @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 Ответ

0 голосов
/ 21 декабря 2018

Проблема

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.
...