Ошибка индексации Numba: Ошибка типа: невозможно индексировать в [0] в i8 * - PullRequest
2 голосов
/ 08 апреля 2019

Я учусь использовать Numba для ускорения функций с помощью jit и векторизации.У меня не было проблем с jit-версией этого кода, но я получаю ошибку индекса с vectorize.Я подозреваю, что ответ на этот вопрос дает правильное представление о том, что существует ошибка типа, но я не уверен, в каком направлении следует изменить индексирование.Ниже приведена функция, с которой я играл, которая выводит числа Фибоначчи до выбранного индекса последовательности.Что не так с индексированием и как я могу исправить свой код, чтобы учесть это?

from numba import vectorize
import numpy as np
from timeit import timeit

@vectorize
def fib(n):
    '''
    Adjusted from:
    https://lectures.quantecon.org/py/numba.html
    https://en.wikipedia.org/wiki/Fibonacci_number
    https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/
    '''

    if n == 1:
        return np.ones(1)
    elif n > 1:
        x = np.empty(n)
        x[0] = 1
        x[1] = 1
        for i in range(2,n):
            x[i] =  x[i-1] + x[i-2]
        return x
    else:
        print('WARNING: Check validity of input.')


print(timeit('fib(10)', globals={'fib':fib}))

Что приводит к следующей ошибке:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/llvmlite/ir/instructions.py", line 619, in __init__
    typ = typ.elements[i]
AttributeError: 'PointerType' object has no attribute 'elements'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/galen/Projects/myjekyllblog/test_code/quantecon_2.py", line 27, in <module>
    print(timeit('fib(10)', globals={'fib':fib}))
  File "/usr/lib/python3.6/timeit.py", line 233, in timeit
    return Timer(stmt, setup, timer, globals).timeit(number)
  File "/usr/lib/python3.6/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/dufunc.py", line 166, in _compile_for_args
    return self._compile_for_argtys(tuple(argtys))
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/dufunc.py", line 188, in _compile_for_argtys
    cres, actual_sig)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/ufuncbuilder.py", line 157, in _build_element_wise_ufunc_wrapper
    cres.objectmode, cres)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/wrappers.py", line 220, in build_ufunc_wrapper
    env=envptr)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/wrappers.py", line 130, in build_fast_loop_body
    env=env)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/wrappers.py", line 23, in _build_ufunc_loop_body
    store(retval)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/wrappers.py", line 126, in store
    out.store_aligned(retval, ind)
  File "/usr/local/lib/python3.6/dist-packages/numba/npyufunc/wrappers.py", line 276, in store_aligned
    self.context.pack_value(self.builder, self.fe_type, value, ptr)
  File "/usr/local/lib/python3.6/dist-packages/numba/targets/base.py", line 482, in pack_value
    dataval = self.data_model_manager[ty].as_data(builder, value)
  File "/usr/local/lib/python3.6/dist-packages/numba/datamodel/models.py", line 558, in as_data
    elems = self._as("as_data", builder, value)
  File "/usr/local/lib/python3.6/dist-packages/numba/datamodel/models.py", line 530, in _as
    self.get(builder, value, i)))
  File "/usr/local/lib/python3.6/dist-packages/numba/datamodel/models.py", line 558, in as_data
    elems = self._as("as_data", builder, value)
  File "/usr/local/lib/python3.6/dist-packages/numba/datamodel/models.py", line 530, in _as
    self.get(builder, value, i)))
  File "/usr/local/lib/python3.6/dist-packages/numba/datamodel/models.py", line 624, in get
    name="extracted." + self._fields[pos])
  File "/usr/local/lib/python3.6/dist-packages/llvmlite/ir/builder.py", line 911, in extract_value
    instr = instructions.ExtractValue(self.block, agg, idx, name=name)
  File "/usr/local/lib/python3.6/dist-packages/llvmlite/ir/instructions.py", line 622, in __init__
    % (list(indices), agg.type))
TypeError: Can't index at [0] in i8*

1 Ответ

1 голос
/ 08 апреля 2019

Ошибка в том, что вы пытаетесь vectorize функция, которую вы можете сказать, по существу не векторизован. Я думаю, что вы путаете функциональность @jit и @vectorize. Чтобы ускорить выполнение ваших функций, вы используете @jit, а @vectorize - для создания универсальных универсальных функций. См. официальную документацию здесь :

Используя vectorize (), вы пишете свою функцию как работающую над вводом скаляры, а не массивы. Numba будет генерировать окружающий цикл (или ядро), обеспечивающее эффективную итерацию по фактическим входам.

Так что, по сути, невозможно создать универсальную универсальную функцию, которая имеет ту же функциональность, что и ваша функция Фибоначчи. Вот ссылка для официальной документации по универсальным функциям , если вы заинтересованы.

Таким образом, чтобы использовать @vectorize, вам нужно создать функцию, которую можно по существу использовать как универсальную функцию с нулевыми значениями. Для ускорения вашего кода вам просто нужно использовать @jit.

...