Galen
Galen

Reputation: 1352

Numba Indexing Error: TypeError: Can't index at [0] in i8*

I'm learning how to use Numba to speed up functions with jit and vectorize. I didn't have any issues with the jit version of this code, but I am getting an index error with vectorize. I suspect this question's answer is getting at the right idea that there is a type error, but I'm not confident on which direction to take on changing the indexing. Included below is the function I've been playing around with, which outputs the Fibonacci numbers up to a chosen index of the sequence. What is going wrong with the indexing, and how I can correct my code to account for it?

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}))

Which results in the following error output.

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*

Upvotes: 2

Views: 509

Answers (1)

Gambit1614
Gambit1614

Reputation: 8801

The error is because you are trying to vectorize a function which you can say is essentially not vectorizable. I think you are confusing the functionality of how @jit and @vectorize work. In order to speed up your functions, you use @jit, while @vectorize is used to create numpy universal functions. See the official documentation here :

Using vectorize(), you write your function as operating over input scalars, rather than arrays. Numba will generate the surrounding loop (or kernel) allowing efficient iteration over the actual inputs.

So it is essentially not possible to create a numpy universal function which has the same functionality as your fibonacci function. Here is the link for official documentation on universal functions if you are interested.

So in order to use @vectorize, you need to create a function which can be essentially used as a numpy universal function. For your purpose of speeding up your code, you simply need to use @jit.

Upvotes: 1

Related Questions